Home | History | Annotate | Download | only in metrics
      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/matchers/SimpleLogMatchingTracker.h"
     16 #include "src/metrics/ValueMetricProducer.h"
     17 #include "src/stats_log_util.h"
     18 #include "metrics_test_helper.h"
     19 #include "tests/statsd_test_util.h"
     20 
     21 #include <gmock/gmock.h>
     22 #include <gtest/gtest.h>
     23 #include <math.h>
     24 #include <stdio.h>
     25 #include <vector>
     26 
     27 using namespace testing;
     28 using android::sp;
     29 using android::util::ProtoReader;
     30 using std::make_shared;
     31 using std::set;
     32 using std::shared_ptr;
     33 using std::unordered_map;
     34 using std::vector;
     35 
     36 #ifdef __ANDROID__
     37 
     38 namespace android {
     39 namespace os {
     40 namespace statsd {
     41 
     42 const ConfigKey kConfigKey(0, 12345);
     43 const int tagId = 1;
     44 const int64_t metricId = 123;
     45 const int64_t atomMatcherId = 678;
     46 const int logEventMatcherIndex = 0;
     47 const int64_t bucketStartTimeNs = 10000000000;
     48 const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
     49 const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
     50 const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
     51 const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
     52 const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
     53 const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
     54 double epsilon = 0.001;
     55 
     56 static void assertPastBucketValuesSingleKey(
     57         const std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>>& mPastBuckets,
     58         const std::initializer_list<int>& expectedValuesList,
     59         const std::initializer_list<int64_t>& expectedDurationNsList) {
     60     std::vector<int> expectedValues(expectedValuesList);
     61     std::vector<int64_t> expectedDurationNs(expectedDurationNsList);
     62     ASSERT_EQ(expectedValues.size(), expectedDurationNs.size());
     63     if (expectedValues.size() == 0) {
     64         ASSERT_EQ(0, mPastBuckets.size());
     65         return;
     66     }
     67 
     68     ASSERT_EQ(1, mPastBuckets.size());
     69     ASSERT_EQ(expectedValues.size(), mPastBuckets.begin()->second.size());
     70 
     71     auto buckets = mPastBuckets.begin()->second;
     72     for (int i = 0; i < expectedValues.size(); i++) {
     73         EXPECT_EQ(expectedValues[i], buckets[i].values[0].long_value)
     74                 << "Values differ at index " << i;
     75         EXPECT_EQ(expectedDurationNs[i], buckets[i].mConditionTrueNs)
     76                 << "Condition duration value differ at index " << i;
     77     }
     78 }
     79 
     80 class ValueMetricProducerTestHelper {
     81 
     82  public:
     83     static shared_ptr<LogEvent> createEvent(int64_t eventTimeNs, int64_t value) {
     84         shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventTimeNs);
     85         event->write(tagId);
     86         event->write(value);
     87         event->write(value);
     88         event->init();
     89         return event;
     90     }
     91 
     92     static sp<ValueMetricProducer> createValueProducerNoConditions(
     93             sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
     94         UidMap uidMap;
     95         SimpleAtomMatcher atomMatcher;
     96         atomMatcher.set_atom_id(tagId);
     97         sp<EventMatcherWizard> eventMatcherWizard =
     98                 new EventMatcherWizard({new SimpleLogMatchingTracker(
     99                         atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    100         sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    101         EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
    102         EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
    103 
    104         sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
    105                 kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
    106                 logEventMatcherIndex, eventMatcherWizard, tagId,
    107                 bucketStartTimeNs, bucketStartTimeNs, pullerManager);
    108         valueProducer->prepareFirstBucket();
    109         return valueProducer;
    110     }
    111 
    112     static sp<ValueMetricProducer> createValueProducerWithCondition(
    113             sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
    114         UidMap uidMap;
    115         SimpleAtomMatcher atomMatcher;
    116         atomMatcher.set_atom_id(tagId);
    117         sp<EventMatcherWizard> eventMatcherWizard =
    118                 new EventMatcherWizard({new SimpleLogMatchingTracker(
    119                         atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    120         sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    121         EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
    122         EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
    123 
    124         sp<ValueMetricProducer> valueProducer =
    125                 new ValueMetricProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
    126                                         eventMatcherWizard, tagId, bucketStartTimeNs,
    127                                         bucketStartTimeNs, pullerManager);
    128         valueProducer->prepareFirstBucket();
    129         valueProducer->mCondition = ConditionState::kFalse;
    130         return valueProducer;
    131     }
    132 
    133     static ValueMetric createMetric() {
    134         ValueMetric metric;
    135         metric.set_id(metricId);
    136         metric.set_bucket(ONE_MINUTE);
    137         metric.mutable_value_field()->set_field(tagId);
    138         metric.mutable_value_field()->add_child()->set_field(2);
    139         metric.set_max_pull_delay_sec(INT_MAX);
    140         return metric;
    141     }
    142 
    143     static ValueMetric createMetricWithCondition() {
    144         ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    145         metric.set_condition(StringToId("SCREEN_ON"));
    146         return metric;
    147     }
    148 };
    149 
    150 
    151 /*
    152  * Tests that the first bucket works correctly
    153  */
    154 TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
    155     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    156 
    157     int64_t startTimeBase = 11;
    158     UidMap uidMap;
    159     SimpleAtomMatcher atomMatcher;
    160     atomMatcher.set_atom_id(tagId);
    161     sp<EventMatcherWizard> eventMatcherWizard =
    162             new EventMatcherWizard({new SimpleLogMatchingTracker(
    163                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    164     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    165     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    166 
    167     // statsd started long ago.
    168     // The metric starts in the middle of the bucket
    169     ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
    170                                       logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
    171                                       22, pullerManager);
    172     valueProducer.prepareFirstBucket();
    173 
    174     EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
    175     EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
    176     EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
    177               valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
    178     EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
    179               valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
    180 }
    181 
    182 /*
    183  * Tests that the first bucket works correctly
    184  */
    185 TEST(ValueMetricProducerTest, TestFirstBucket) {
    186     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    187 
    188     UidMap uidMap;
    189     SimpleAtomMatcher atomMatcher;
    190     atomMatcher.set_atom_id(tagId);
    191     sp<EventMatcherWizard> eventMatcherWizard =
    192             new EventMatcherWizard({new SimpleLogMatchingTracker(
    193                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    194     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    195     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    196 
    197     // statsd started long ago.
    198     // The metric starts in the middle of the bucket
    199     ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
    200                                       logEventMatcherIndex, eventMatcherWizard, -1, 5,
    201                                       600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
    202     valueProducer.prepareFirstBucket();
    203 
    204     EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
    205     EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
    206     EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
    207 }
    208 
    209 /*
    210  * Tests pulled atoms with no conditions
    211  */
    212 TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
    213     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    214     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    215     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    216             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    217                 data->clear();
    218                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
    219                 event->write(tagId);
    220                 event->write(3);
    221                 event->init();
    222                 data->push_back(event);
    223                 return true;
    224             }));
    225 
    226     sp<ValueMetricProducer> valueProducer =
    227             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
    228 
    229     vector<shared_ptr<LogEvent>> allData;
    230     allData.clear();
    231     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    232     event->write(tagId);
    233     event->write(11);
    234     event->init();
    235     allData.push_back(event);
    236 
    237     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    238     // has one slice
    239     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    240     ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    241 
    242     EXPECT_EQ(true, curInterval.hasBase);
    243     EXPECT_EQ(11, curInterval.base.long_value);
    244     EXPECT_EQ(false, curInterval.hasValue);
    245     EXPECT_EQ(8, curInterval.value.long_value);
    246     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    247     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    248     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    249 
    250     allData.clear();
    251     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    252     event->write(tagId);
    253     event->write(23);
    254     event->init();
    255     allData.push_back(event);
    256     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
    257     // has one slice
    258     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    259     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    260 
    261     EXPECT_EQ(true, curInterval.hasBase);
    262     EXPECT_EQ(23, curInterval.base.long_value);
    263     EXPECT_EQ(false, curInterval.hasValue);
    264     EXPECT_EQ(12, curInterval.value.long_value);
    265     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    266     EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
    267     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    268     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    269     EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
    270     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
    271 
    272     allData.clear();
    273     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
    274     event->write(tagId);
    275     event->write(36);
    276     event->init();
    277     allData.push_back(event);
    278     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
    279     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    280     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    281 
    282     EXPECT_EQ(true, curInterval.hasBase);
    283     EXPECT_EQ(36, curInterval.base.long_value);
    284     EXPECT_EQ(false, curInterval.hasValue);
    285     EXPECT_EQ(13, curInterval.value.long_value);
    286     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    287     EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
    288     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    289     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    290     EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
    291     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
    292     EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
    293     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
    294 }
    295 
    296 TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
    297     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    298     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    299     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    300             // Initialize bucket.
    301             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    302                 data->clear();
    303                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
    304                 event->write(tagId);
    305                 event->write(1);
    306                 event->init();
    307                 data->push_back(event);
    308                 return true;
    309             }))
    310             // Partial bucket.
    311             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    312                 data->clear();
    313                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
    314                 event->write(tagId);
    315                 event->write(5);
    316                 event->init();
    317                 data->push_back(event);
    318                 return true;
    319             }));
    320 
    321     sp<ValueMetricProducer> valueProducer =
    322             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
    323 
    324     // First bucket ends.
    325     vector<shared_ptr<LogEvent>> allData;
    326     allData.clear();
    327     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
    328     event->write(tagId);
    329     event->write(2);
    330     event->init();
    331     allData.push_back(event);
    332     valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
    333 
    334     // Partial buckets created in 2nd bucket.
    335     valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
    336 
    337     // One full bucket and one partial bucket.
    338     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    339     vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second;
    340     EXPECT_EQ(2UL, buckets.size());
    341     // Full bucket (2 - 1)
    342     EXPECT_EQ(1, buckets[0].values[0].long_value);
    343     EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs);
    344     // Full bucket (5 - 3)
    345     EXPECT_EQ(3, buckets[1].values[0].long_value);
    346     // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2]
    347     EXPECT_EQ(2, buckets[1].mConditionTrueNs);
    348 }
    349 
    350 /*
    351  * Tests pulled atoms with filtering
    352  */
    353 TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
    354     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    355 
    356     UidMap uidMap;
    357     SimpleAtomMatcher atomMatcher;
    358     atomMatcher.set_atom_id(tagId);
    359     auto keyValue = atomMatcher.add_field_value_matcher();
    360     keyValue->set_field(1);
    361     keyValue->set_eq_int(3);
    362     sp<EventMatcherWizard> eventMatcherWizard =
    363             new EventMatcherWizard({new SimpleLogMatchingTracker(
    364                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    365     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    366     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    367     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
    368     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
    369     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    370             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    371                 data->clear();
    372                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
    373                 event->write(3);
    374                 event->write(3);
    375                 event->init();
    376                 data->push_back(event);
    377                 return true;
    378             }));
    379 
    380     sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
    381             kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
    382             logEventMatcherIndex, eventMatcherWizard, tagId,
    383             bucketStartTimeNs, bucketStartTimeNs, pullerManager);
    384     valueProducer->prepareFirstBucket();
    385 
    386     vector<shared_ptr<LogEvent>> allData;
    387     allData.clear();
    388     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    389     event->write(3);
    390     event->write(11);
    391     event->init();
    392     allData.push_back(event);
    393 
    394     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    395     // has one slice
    396     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    397     ValueMetricProducer::Interval curInterval =
    398             valueProducer->mCurrentSlicedBucket.begin()->second[0];
    399 
    400     EXPECT_EQ(true, curInterval.hasBase);
    401     EXPECT_EQ(11, curInterval.base.long_value);
    402     EXPECT_EQ(false, curInterval.hasValue);
    403     EXPECT_EQ(8, curInterval.value.long_value);
    404     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    405     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    406     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    407 
    408     allData.clear();
    409     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    410     event->write(4);
    411     event->write(23);
    412     event->init();
    413     allData.push_back(event);
    414     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
    415     // No new data seen, so data has been cleared.
    416     EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
    417 
    418     EXPECT_EQ(true, curInterval.hasBase);
    419     EXPECT_EQ(11, curInterval.base.long_value);
    420     EXPECT_EQ(false, curInterval.hasValue);
    421     EXPECT_EQ(8, curInterval.value.long_value);
    422     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    423     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    424     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    425 
    426     allData.clear();
    427     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
    428     event->write(3);
    429     event->write(36);
    430     event->init();
    431     allData.push_back(event);
    432     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
    433     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    434     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    435 
    436     // the base was reset
    437     EXPECT_EQ(true, curInterval.hasBase);
    438     EXPECT_EQ(36, curInterval.base.long_value);
    439     EXPECT_EQ(false, curInterval.hasValue);
    440     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    441     EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
    442     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
    443     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
    444 }
    445 
    446 /*
    447  * Tests pulled atoms with no conditions and take absolute value after reset
    448  */
    449 TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
    450     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    451     metric.set_use_absolute_value_on_reset(true);
    452 
    453     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    454     EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
    455     sp<ValueMetricProducer> valueProducer =
    456             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
    457 
    458     vector<shared_ptr<LogEvent>> allData;
    459     allData.clear();
    460     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    461     event->write(tagId);
    462     event->write(11);
    463     event->init();
    464     allData.push_back(event);
    465 
    466     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    467     // has one slice
    468     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    469     ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    470 
    471     EXPECT_EQ(true, curInterval.hasBase);
    472     EXPECT_EQ(11, curInterval.base.long_value);
    473     EXPECT_EQ(false, curInterval.hasValue);
    474     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
    475 
    476     allData.clear();
    477     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    478     event->write(tagId);
    479     event->write(10);
    480     event->init();
    481     allData.push_back(event);
    482     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
    483     // has one slice
    484     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    485     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    486     EXPECT_EQ(true, curInterval.hasBase);
    487     EXPECT_EQ(10, curInterval.base.long_value);
    488     EXPECT_EQ(false, curInterval.hasValue);
    489     EXPECT_EQ(10, curInterval.value.long_value);
    490     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    491     EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
    492     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
    493 
    494     allData.clear();
    495     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
    496     event->write(tagId);
    497     event->write(36);
    498     event->init();
    499     allData.push_back(event);
    500     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
    501     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    502     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    503     EXPECT_EQ(true, curInterval.hasBase);
    504     EXPECT_EQ(36, curInterval.base.long_value);
    505     EXPECT_EQ(false, curInterval.hasValue);
    506     EXPECT_EQ(26, curInterval.value.long_value);
    507     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    508     EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
    509     EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    510     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    511     EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
    512     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
    513 }
    514 
    515 /*
    516  * Tests pulled atoms with no conditions and take zero value after reset
    517  */
    518 TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
    519     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    520     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    521     EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
    522     sp<ValueMetricProducer> valueProducer =
    523             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
    524 
    525     vector<shared_ptr<LogEvent>> allData;
    526     allData.clear();
    527     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    528     event->write(tagId);
    529     event->write(11);
    530     event->init();
    531     allData.push_back(event);
    532 
    533     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    534     // has one slice
    535     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    536     ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    537 
    538     EXPECT_EQ(true, curInterval.hasBase);
    539     EXPECT_EQ(11, curInterval.base.long_value);
    540     EXPECT_EQ(false, curInterval.hasValue);
    541     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
    542 
    543     allData.clear();
    544     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    545     event->write(tagId);
    546     event->write(10);
    547     event->init();
    548     allData.push_back(event);
    549     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
    550     // has one slice
    551     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    552     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    553     EXPECT_EQ(true, curInterval.hasBase);
    554     EXPECT_EQ(10, curInterval.base.long_value);
    555     EXPECT_EQ(false, curInterval.hasValue);
    556     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
    557 
    558     allData.clear();
    559     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
    560     event->write(tagId);
    561     event->write(36);
    562     event->init();
    563     allData.push_back(event);
    564     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
    565     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    566     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    567     EXPECT_EQ(true, curInterval.hasBase);
    568     EXPECT_EQ(36, curInterval.base.long_value);
    569     EXPECT_EQ(false, curInterval.hasValue);
    570     EXPECT_EQ(26, curInterval.value.long_value);
    571     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
    572     EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
    573     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
    574 }
    575 
    576 /*
    577  * Test pulled event with non sliced condition.
    578  */
    579 TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
    580     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
    581 
    582     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    583 
    584     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    585             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    586                 data->clear();
    587                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
    588                 event->write(tagId);
    589                 event->write(100);
    590                 event->init();
    591                 data->push_back(event);
    592                 return true;
    593             }))
    594             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    595                 data->clear();
    596                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    597                 event->write(tagId);
    598                 event->write(130);
    599                 event->init();
    600                 data->push_back(event);
    601                 return true;
    602             }))
    603             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    604                 data->clear();
    605                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    606                 event->write(tagId);
    607                 event->write(180);
    608                 event->init();
    609                 data->push_back(event);
    610                 return true;
    611             }));
    612 
    613     sp<ValueMetricProducer> valueProducer =
    614             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
    615 
    616     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
    617 
    618     // has one slice
    619     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    620     ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    621     // startUpdated:false sum:0 start:100
    622     EXPECT_EQ(true, curInterval.hasBase);
    623     EXPECT_EQ(100, curInterval.base.long_value);
    624     EXPECT_EQ(false, curInterval.hasValue);
    625     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
    626 
    627     vector<shared_ptr<LogEvent>> allData;
    628     allData.clear();
    629     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    630     event->write(1);
    631     event->write(110);
    632     event->init();
    633     allData.push_back(event);
    634     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    635     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
    636 
    637     // has one slice
    638     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    639     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    640     EXPECT_EQ(true, curInterval.hasBase);
    641     EXPECT_EQ(110, curInterval.base.long_value);
    642     EXPECT_EQ(false, curInterval.hasValue);
    643     EXPECT_EQ(10, curInterval.value.long_value);
    644 
    645     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
    646     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8});
    647 
    648     // has one slice
    649     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
    650     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
    651     EXPECT_EQ(true, curInterval.hasValue);
    652     EXPECT_EQ(20, curInterval.value.long_value);
    653     EXPECT_EQ(false, curInterval.hasBase);
    654 
    655     valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
    656     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1});
    657 }
    658 
    659 TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
    660     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    661 
    662     UidMap uidMap;
    663     SimpleAtomMatcher atomMatcher;
    664     atomMatcher.set_atom_id(tagId);
    665     sp<EventMatcherWizard> eventMatcherWizard =
    666             new EventMatcherWizard({new SimpleLogMatchingTracker(
    667                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    668     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    669     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    670     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
    671                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
    672                                       pullerManager);
    673     valueProducer.prepareFirstBucket();
    674 
    675     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
    676     event1->write(1);
    677     event1->write(10);
    678     event1->init();
    679     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
    680     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    681 
    682     valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
    683     EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    684     EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
    685 
    686     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
    687     event2->write(1);
    688     event2->write(10);
    689     event2->init();
    690     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
    691     EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    692     EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
    693 
    694     // Next value should create a new bucket.
    695     shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
    696     event3->write(1);
    697     event3->write(10);
    698     event3->init();
    699     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
    700     EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    701     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
    702 }
    703 
    704 TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
    705     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    706 
    707     UidMap uidMap;
    708     SimpleAtomMatcher atomMatcher;
    709     atomMatcher.set_atom_id(tagId);
    710     sp<EventMatcherWizard> eventMatcherWizard =
    711             new EventMatcherWizard({new SimpleLogMatchingTracker(
    712                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    713     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    714     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    715     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
    716     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
    717     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    718             .WillOnce(Return(true))
    719             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    720                 data->clear();
    721                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
    722                 event->write(tagId);
    723                 event->write(120);
    724                 event->init();
    725                 data->push_back(event);
    726                 return true;
    727             }));
    728     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
    729                                       eventMatcherWizard, tagId, bucketStartTimeNs,
    730                                       bucketStartTimeNs, pullerManager);
    731     valueProducer.prepareFirstBucket();
    732 
    733     vector<shared_ptr<LogEvent>> allData;
    734     allData.clear();
    735     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    736     event->write(tagId);
    737     event->write(100);
    738     event->init();
    739     allData.push_back(event);
    740 
    741     valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    742     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    743 
    744     valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
    745     EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    746     EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
    747     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150});
    748 
    749     allData.clear();
    750     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
    751     event->write(tagId);
    752     event->write(150);
    753     event->init();
    754     allData.push_back(event);
    755     valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
    756     EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    757     EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
    758     EXPECT_EQ(20L,
    759               valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
    760     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30},
    761                                     {150, bucketSizeNs - 150});
    762 }
    763 
    764 TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
    765     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    766     metric.set_split_bucket_for_app_upgrade(false);
    767 
    768     UidMap uidMap;
    769     SimpleAtomMatcher atomMatcher;
    770     atomMatcher.set_atom_id(tagId);
    771     sp<EventMatcherWizard> eventMatcherWizard =
    772             new EventMatcherWizard({new SimpleLogMatchingTracker(
    773                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    774     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    775     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    776     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
    777     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
    778     EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
    779     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
    780                                       eventMatcherWizard, tagId, bucketStartTimeNs,
    781                                       bucketStartTimeNs, pullerManager);
    782     valueProducer.prepareFirstBucket();
    783 
    784     vector<shared_ptr<LogEvent>> allData;
    785     allData.clear();
    786     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
    787     event->write(tagId);
    788     event->write(100);
    789     event->init();
    790     allData.push_back(event);
    791 
    792     valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
    793     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    794 
    795     valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
    796     EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    797     EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
    798 }
    799 
    800 TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
    801     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
    802 
    803     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    804     EXPECT_CALL(*pullerManager, Pull(tagId, _))
    805             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    806                 data->clear();
    807                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
    808                 event->write(tagId);
    809                 event->write(100);
    810                 event->init();
    811                 data->push_back(event);
    812                 return true;
    813             }))
    814             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    815                 data->clear();
    816                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
    817                 event->write(tagId);
    818                 event->write(120);
    819                 event->init();
    820                 data->push_back(event);
    821                 return true;
    822             }));
    823     sp<ValueMetricProducer> valueProducer =
    824             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
    825 
    826     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
    827 
    828     valueProducer->onConditionChanged(false, bucket2StartTimeNs-100);
    829     EXPECT_FALSE(valueProducer->mCondition);
    830 
    831     valueProducer->notifyAppUpgrade(bucket2StartTimeNs-50, "ANY.APP", 1, 1);
    832     // Expect one full buckets already done and starting a partial bucket.
    833     EXPECT_EQ(bucket2StartTimeNs-50, valueProducer->mCurrentBucketStartTimeNs);
    834     EXPECT_EQ(1UL, valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
    835     EXPECT_EQ(bucketStartTimeNs,
    836               valueProducer->mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
    837     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
    838                                     {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)});
    839     EXPECT_FALSE(valueProducer->mCondition);
    840 }
    841 
    842 TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
    843     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    844 
    845     UidMap uidMap;
    846     SimpleAtomMatcher atomMatcher;
    847     atomMatcher.set_atom_id(tagId);
    848     sp<EventMatcherWizard> eventMatcherWizard =
    849             new EventMatcherWizard({new SimpleLogMatchingTracker(
    850                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    851     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    852     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    853 
    854     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
    855                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
    856                                       pullerManager);
    857     valueProducer.prepareFirstBucket();
    858 
    859     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
    860     event1->write(1);
    861     event1->write(10);
    862     event1->init();
    863     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
    864     event2->write(1);
    865     event2->write(20);
    866     event2->init();
    867     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
    868     // has one slice
    869     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    870     ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
    871     EXPECT_EQ(10, curInterval.value.long_value);
    872     EXPECT_EQ(true, curInterval.hasValue);
    873 
    874     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
    875 
    876     // has one slice
    877     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    878     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
    879     EXPECT_EQ(30, curInterval.value.long_value);
    880 
    881     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
    882     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs});
    883 }
    884 
    885 TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
    886     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    887 
    888     UidMap uidMap;
    889     SimpleAtomMatcher atomMatcher;
    890     atomMatcher.set_atom_id(tagId);
    891     sp<EventMatcherWizard> eventMatcherWizard =
    892             new EventMatcherWizard({new SimpleLogMatchingTracker(
    893                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    894     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    895     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    896 
    897     ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
    898                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
    899                                       pullerManager);
    900     valueProducer.prepareFirstBucket();
    901     valueProducer.mCondition = ConditionState::kFalse;
    902 
    903     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
    904     event1->write(1);
    905     event1->write(10);
    906     event1->init();
    907     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
    908     // has 1 slice
    909     EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
    910 
    911     valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
    912     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
    913     event2->write(1);
    914     event2->write(20);
    915     event2->init();
    916     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
    917 
    918     // has one slice
    919     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    920     ValueMetricProducer::Interval curInterval =
    921             valueProducer.mCurrentSlicedBucket.begin()->second[0];
    922     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
    923     EXPECT_EQ(20, curInterval.value.long_value);
    924 
    925     shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
    926     event3->write(1);
    927     event3->write(30);
    928     event3->init();
    929     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
    930 
    931     // has one slice
    932     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    933     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
    934     EXPECT_EQ(50, curInterval.value.long_value);
    935 
    936     valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
    937     shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 40);
    938     event4->write(1);
    939     event4->write(40);
    940     event4->init();
    941     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
    942 
    943     // has one slice
    944     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
    945     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
    946     EXPECT_EQ(50, curInterval.value.long_value);
    947 
    948     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
    949     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20});
    950 }
    951 
    952 TEST(ValueMetricProducerTest, TestAnomalyDetection) {
    953     sp<AlarmMonitor> alarmMonitor;
    954     Alert alert;
    955     alert.set_id(101);
    956     alert.set_metric_id(metricId);
    957     alert.set_trigger_if_sum_gt(130);
    958     alert.set_num_buckets(2);
    959     const int32_t refPeriodSec = 3;
    960     alert.set_refractory_period_secs(refPeriodSec);
    961 
    962     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
    963 
    964     UidMap uidMap;
    965     SimpleAtomMatcher atomMatcher;
    966     atomMatcher.set_atom_id(tagId);
    967     sp<EventMatcherWizard> eventMatcherWizard =
    968             new EventMatcherWizard({new SimpleLogMatchingTracker(
    969                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
    970     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
    971     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
    972     ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
    973                                       logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
    974                                       bucketStartTimeNs, bucketStartTimeNs, pullerManager);
    975     valueProducer.prepareFirstBucket();
    976 
    977     sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
    978 
    979 
    980     shared_ptr<LogEvent> event1
    981             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1 * NS_PER_SEC);
    982     event1->write(161);
    983     event1->write(10); // value of interest
    984     event1->init();
    985     shared_ptr<LogEvent> event2
    986             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 + NS_PER_SEC);
    987     event2->write(162);
    988     event2->write(20); // value of interest
    989     event2->init();
    990     shared_ptr<LogEvent> event3
    991             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC);
    992     event3->write(163);
    993     event3->write(130); // value of interest
    994     event3->init();
    995     shared_ptr<LogEvent> event4
    996             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC);
    997     event4->write(35);
    998     event4->write(1); // value of interest
    999     event4->init();
   1000     shared_ptr<LogEvent> event5
   1001             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC);
   1002     event5->write(45);
   1003     event5->write(150); // value of interest
   1004     event5->init();
   1005     shared_ptr<LogEvent> event6
   1006             = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC);
   1007     event6->write(25);
   1008     event6->write(160); // value of interest
   1009     event6->init();
   1010 
   1011     // Two events in bucket #0.
   1012     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1013     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1014     // Value sum == 30 <= 130.
   1015     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
   1016 
   1017     // One event in bucket #2. No alarm as bucket #0 is trashed out.
   1018     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
   1019     // Value sum == 130 <= 130.
   1020     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
   1021 
   1022     // Three events in bucket #3.
   1023     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
   1024     // Anomaly at event 4 since Value sum == 131 > 130!
   1025     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
   1026             std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
   1027     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event5);
   1028     // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
   1029     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
   1030             std::ceil(1.0 * event4->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
   1031 
   1032     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event6);
   1033     // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
   1034     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
   1035             std::ceil(1.0 * event6->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
   1036 }
   1037 
   1038 // Test value metric no condition, the pull on bucket boundary come in time and too late
   1039 TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
   1040     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1041     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1042     EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
   1043     sp<ValueMetricProducer> valueProducer =
   1044             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   1045 
   1046     vector<shared_ptr<LogEvent>> allData;
   1047     // pull 1
   1048     allData.clear();
   1049     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1050     event->write(tagId);
   1051     event->write(11);
   1052     event->init();
   1053     allData.push_back(event);
   1054 
   1055     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   1056     // has one slice
   1057     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1058     ValueMetricProducer::Interval curInterval =
   1059             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1060 
   1061     // startUpdated:true sum:0 start:11
   1062     EXPECT_EQ(true, curInterval.hasBase);
   1063     EXPECT_EQ(11, curInterval.base.long_value);
   1064     EXPECT_EQ(false, curInterval.hasValue);
   1065     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1066 
   1067     // pull 2 at correct time
   1068     allData.clear();
   1069     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
   1070     event->write(tagId);
   1071     event->write(23);
   1072     event->init();
   1073     allData.push_back(event);
   1074     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
   1075     // has one slice
   1076     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1077     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1078     // tartUpdated:false sum:12
   1079     EXPECT_EQ(true, curInterval.hasBase);
   1080     EXPECT_EQ(23, curInterval.base.long_value);
   1081     EXPECT_EQ(false, curInterval.hasValue);
   1082     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
   1083 
   1084     // pull 3 come late.
   1085     // The previous bucket gets closed with error. (Has start value 23, no ending)
   1086     // Another bucket gets closed with error. (No start, but ending with 36)
   1087     // The new bucket is back to normal.
   1088     allData.clear();
   1089     event = make_shared<LogEvent>(tagId, bucket6StartTimeNs + 1);
   1090     event->write(tagId);
   1091     event->write(36);
   1092     event->init();
   1093     allData.push_back(event);
   1094     valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
   1095     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1096     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1097     // startUpdated:false sum:12
   1098     EXPECT_EQ(true, curInterval.hasBase);
   1099     EXPECT_EQ(36, curInterval.base.long_value);
   1100     EXPECT_EQ(false, curInterval.hasValue);
   1101     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs});
   1102 }
   1103 
   1104 /*
   1105  * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
   1106  * was delivered late.
   1107  */
   1108 TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
   1109     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   1110 
   1111     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1112     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1113             // condition becomes true
   1114             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1115                 data->clear();
   1116                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   1117                 event->write(tagId);
   1118                 event->write(100);
   1119                 event->init();
   1120                 data->push_back(event);
   1121                 return true;
   1122             }))
   1123             // condition becomes false
   1124             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1125                 data->clear();
   1126                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1127                 event->write(tagId);
   1128                 event->write(120);
   1129                 event->init();
   1130                 data->push_back(event);
   1131                 return true;
   1132             }));
   1133     sp<ValueMetricProducer> valueProducer =
   1134             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   1135 
   1136     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   1137 
   1138     // has one slice
   1139     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1140     ValueMetricProducer::Interval curInterval =
   1141             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1142     EXPECT_EQ(true, curInterval.hasBase);
   1143     EXPECT_EQ(100, curInterval.base.long_value);
   1144     EXPECT_EQ(false, curInterval.hasValue);
   1145     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1146 
   1147     // pull on bucket boundary come late, condition change happens before it
   1148     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
   1149     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1150     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
   1151     EXPECT_EQ(false, curInterval.hasBase);
   1152 
   1153     // Now the alarm is delivered.
   1154     // since the condition turned to off before this pull finish, it has no effect
   1155     vector<shared_ptr<LogEvent>> allData;
   1156     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 110));
   1157     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   1158 
   1159     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
   1160     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1161     EXPECT_EQ(false, curInterval.hasBase);
   1162     EXPECT_EQ(false, curInterval.hasValue);
   1163 }
   1164 
   1165 /*
   1166  * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
   1167  * change to false, and then true again. This is due to alarm delivered late.
   1168  */
   1169 TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
   1170     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   1171 
   1172     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1173     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1174             // condition becomes true
   1175             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1176                 data->clear();
   1177                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   1178                 event->write(tagId);
   1179                 event->write(100);
   1180                 event->init();
   1181                 data->push_back(event);
   1182                 return true;
   1183             }))
   1184             // condition becomes false
   1185             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1186                 data->clear();
   1187                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1188                 event->write(tagId);
   1189                 event->write(120);
   1190                 event->init();
   1191                 data->push_back(event);
   1192                 return true;
   1193             }))
   1194             // condition becomes true again
   1195             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1196                 data->clear();
   1197                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
   1198                 event->write(tagId);
   1199                 event->write(130);
   1200                 event->init();
   1201                 data->push_back(event);
   1202                 return true;
   1203             }));
   1204 
   1205     sp<ValueMetricProducer> valueProducer =
   1206             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   1207 
   1208     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   1209 
   1210     // has one slice
   1211     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1212     ValueMetricProducer::Interval curInterval =
   1213             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1214     // startUpdated:false sum:0 start:100
   1215     EXPECT_EQ(true, curInterval.hasBase);
   1216     EXPECT_EQ(100, curInterval.base.long_value);
   1217     EXPECT_EQ(false, curInterval.hasValue);
   1218     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1219 
   1220     // pull on bucket boundary come late, condition change happens before it
   1221     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
   1222     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
   1223     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1224     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1225     EXPECT_EQ(false, curInterval.hasBase);
   1226     EXPECT_EQ(false, curInterval.hasValue);
   1227 
   1228     // condition changed to true again, before the pull alarm is delivered
   1229     valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
   1230     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
   1231     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1232     EXPECT_EQ(true, curInterval.hasBase);
   1233     EXPECT_EQ(130, curInterval.base.long_value);
   1234     EXPECT_EQ(false, curInterval.hasValue);
   1235 
   1236     // Now the alarm is delivered, but it is considered late, the data will be used
   1237     // for the new bucket since it was just pulled.
   1238     vector<shared_ptr<LogEvent>> allData;
   1239     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 50, 140));
   1240     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
   1241 
   1242     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1243     EXPECT_EQ(true, curInterval.hasBase);
   1244     EXPECT_EQ(140, curInterval.base.long_value);
   1245     EXPECT_EQ(true, curInterval.hasValue);
   1246     EXPECT_EQ(10, curInterval.value.long_value);
   1247     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8});
   1248 
   1249     allData.clear();
   1250     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs, 160));
   1251     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
   1252     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20, 30},
   1253                                     {bucketSizeNs - 8, bucketSizeNs - 24});
   1254 }
   1255 
   1256 TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
   1257     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1258     metric.set_aggregation_type(ValueMetric::MIN);
   1259 
   1260     UidMap uidMap;
   1261     SimpleAtomMatcher atomMatcher;
   1262     atomMatcher.set_atom_id(tagId);
   1263     sp<EventMatcherWizard> eventMatcherWizard =
   1264             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1265                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1266     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1267     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1268 
   1269     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1270                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1271                                       pullerManager);
   1272     valueProducer.prepareFirstBucket();
   1273 
   1274     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1275     event1->write(1);
   1276     event1->write(10);
   1277     event1->init();
   1278     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
   1279     event2->write(1);
   1280     event2->write(20);
   1281     event2->init();
   1282     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1283     // has one slice
   1284     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1285     ValueMetricProducer::Interval curInterval =
   1286             valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1287     EXPECT_EQ(10, curInterval.value.long_value);
   1288     EXPECT_EQ(true, curInterval.hasValue);
   1289 
   1290     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1291 
   1292     // has one slice
   1293     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1294     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1295     EXPECT_EQ(10, curInterval.value.long_value);
   1296 
   1297     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
   1298     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs});
   1299 }
   1300 
   1301 TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
   1302     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1303     metric.set_aggregation_type(ValueMetric::MAX);
   1304 
   1305     UidMap uidMap;
   1306     SimpleAtomMatcher atomMatcher;
   1307     atomMatcher.set_atom_id(tagId);
   1308     sp<EventMatcherWizard> eventMatcherWizard =
   1309             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1310                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1311     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1312     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1313 
   1314     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1315                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1316                                       pullerManager);
   1317     valueProducer.prepareFirstBucket();
   1318 
   1319     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1320     event1->write(1);
   1321     event1->write(10);
   1322     event1->init();
   1323     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
   1324     event2->write(1);
   1325     event2->write(20);
   1326     event2->init();
   1327     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1328     // has one slice
   1329     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1330     ValueMetricProducer::Interval curInterval =
   1331             valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1332     EXPECT_EQ(10, curInterval.value.long_value);
   1333     EXPECT_EQ(true, curInterval.hasValue);
   1334 
   1335     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1336 
   1337     // has one slice
   1338     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1339     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1340     EXPECT_EQ(20, curInterval.value.long_value);
   1341 
   1342     valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
   1343     /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.size()); */
   1344     /* EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size()); */
   1345     /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */
   1346 }
   1347 
   1348 TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
   1349     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1350     metric.set_aggregation_type(ValueMetric::AVG);
   1351 
   1352     UidMap uidMap;
   1353     SimpleAtomMatcher atomMatcher;
   1354     atomMatcher.set_atom_id(tagId);
   1355     sp<EventMatcherWizard> eventMatcherWizard =
   1356             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1357                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1358     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1359     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1360 
   1361     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1362                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1363                                       pullerManager);
   1364     valueProducer.prepareFirstBucket();
   1365 
   1366     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1367     event1->write(1);
   1368     event1->write(10);
   1369     event1->init();
   1370     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
   1371     event2->write(1);
   1372     event2->write(15);
   1373     event2->init();
   1374     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1375     // has one slice
   1376     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1377     ValueMetricProducer::Interval curInterval;
   1378     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1379     EXPECT_EQ(10, curInterval.value.long_value);
   1380     EXPECT_EQ(true, curInterval.hasValue);
   1381     EXPECT_EQ(1, curInterval.sampleSize);
   1382 
   1383     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1384 
   1385     // has one slice
   1386     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1387     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1388     EXPECT_EQ(25, curInterval.value.long_value);
   1389     EXPECT_EQ(2, curInterval.sampleSize);
   1390 
   1391     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
   1392     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
   1393     EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
   1394 
   1395     EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
   1396                          12.5) < epsilon);
   1397 }
   1398 
   1399 TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
   1400     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1401     metric.set_aggregation_type(ValueMetric::SUM);
   1402 
   1403     UidMap uidMap;
   1404     SimpleAtomMatcher atomMatcher;
   1405     atomMatcher.set_atom_id(tagId);
   1406     sp<EventMatcherWizard> eventMatcherWizard =
   1407             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1408                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1409     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1410     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1411 
   1412     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1413                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1414                                       pullerManager);
   1415     valueProducer.prepareFirstBucket();
   1416 
   1417     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1418     event1->write(1);
   1419     event1->write(10);
   1420     event1->init();
   1421     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
   1422     event2->write(1);
   1423     event2->write(15);
   1424     event2->init();
   1425     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1426     // has one slice
   1427     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1428     ValueMetricProducer::Interval curInterval =
   1429             valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1430     EXPECT_EQ(10, curInterval.value.long_value);
   1431     EXPECT_EQ(true, curInterval.hasValue);
   1432 
   1433     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1434 
   1435     // has one slice
   1436     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1437     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1438     EXPECT_EQ(25, curInterval.value.long_value);
   1439 
   1440     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
   1441     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs});
   1442 }
   1443 
   1444 TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
   1445     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1446     metric.set_aggregation_type(ValueMetric::MIN);
   1447     metric.set_use_diff(true);
   1448 
   1449     UidMap uidMap;
   1450     SimpleAtomMatcher atomMatcher;
   1451     atomMatcher.set_atom_id(tagId);
   1452     sp<EventMatcherWizard> eventMatcherWizard =
   1453             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1454                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1455     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1456     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1457 
   1458     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1459                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1460                                       pullerManager);
   1461     valueProducer.prepareFirstBucket();
   1462 
   1463     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1464     event1->write(1);
   1465     event1->write(10);
   1466     event1->init();
   1467     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
   1468     event2->write(1);
   1469     event2->write(15);
   1470     event2->init();
   1471     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1472     // has one slice
   1473     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1474     ValueMetricProducer::Interval curInterval =
   1475             valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1476     EXPECT_EQ(true, curInterval.hasBase);
   1477     EXPECT_EQ(10, curInterval.base.long_value);
   1478     EXPECT_EQ(false, curInterval.hasValue);
   1479 
   1480     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1481 
   1482     // has one slice
   1483     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1484     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1485     EXPECT_EQ(true, curInterval.hasValue);
   1486     EXPECT_EQ(5, curInterval.value.long_value);
   1487 
   1488     // no change in data.
   1489     shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
   1490     event3->write(1);
   1491     event3->write(15);
   1492     event3->init();
   1493     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
   1494     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1495     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1496     EXPECT_EQ(true, curInterval.hasBase);
   1497     EXPECT_EQ(15, curInterval.base.long_value);
   1498     EXPECT_EQ(true, curInterval.hasValue);
   1499 
   1500     shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
   1501     event4->write(1);
   1502     event4->write(15);
   1503     event4->init();
   1504     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
   1505     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1506     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1507     EXPECT_EQ(true, curInterval.hasBase);
   1508     EXPECT_EQ(15, curInterval.base.long_value);
   1509     EXPECT_EQ(true, curInterval.hasValue);
   1510 
   1511     valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
   1512     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
   1513     EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
   1514     assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs});
   1515 }
   1516 
   1517 TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
   1518     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1519     metric.mutable_value_field()->add_child()->set_field(3);
   1520     metric.set_aggregation_type(ValueMetric::MIN);
   1521     metric.set_use_diff(true);
   1522 
   1523     UidMap uidMap;
   1524     SimpleAtomMatcher atomMatcher;
   1525     atomMatcher.set_atom_id(tagId);
   1526     sp<EventMatcherWizard> eventMatcherWizard =
   1527             new EventMatcherWizard({new SimpleLogMatchingTracker(
   1528                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   1529     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   1530     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1531 
   1532     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   1533                                       eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
   1534                                       pullerManager);
   1535     valueProducer.prepareFirstBucket();
   1536 
   1537     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   1538     event1->write(1);
   1539     event1->write(10);
   1540     event1->write(20);
   1541     event1->init();
   1542     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
   1543     event2->write(1);
   1544     event2->write(15);
   1545     event2->write(22);
   1546     event2->init();
   1547     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
   1548     // has one slice
   1549     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1550     ValueMetricProducer::Interval curInterval0 =
   1551         valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1552     ValueMetricProducer::Interval curInterval1 =
   1553         valueProducer.mCurrentSlicedBucket.begin()->second[1];
   1554     EXPECT_EQ(true, curInterval0.hasBase);
   1555     EXPECT_EQ(10, curInterval0.base.long_value);
   1556     EXPECT_EQ(false, curInterval0.hasValue);
   1557     EXPECT_EQ(true, curInterval1.hasBase);
   1558     EXPECT_EQ(20, curInterval1.base.long_value);
   1559     EXPECT_EQ(false, curInterval1.hasValue);
   1560 
   1561     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
   1562 
   1563     // has one slice
   1564     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1565     curInterval0 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1566     curInterval1 = valueProducer.mCurrentSlicedBucket.begin()->second[1];
   1567     EXPECT_EQ(true, curInterval0.hasValue);
   1568     EXPECT_EQ(5, curInterval0.value.long_value);
   1569     EXPECT_EQ(true, curInterval1.hasValue);
   1570     EXPECT_EQ(2, curInterval1.value.long_value);
   1571 
   1572     // no change in first value field
   1573     shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
   1574     event3->write(1);
   1575     event3->write(15);
   1576     event3->write(25);
   1577     event3->init();
   1578     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
   1579     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1580     curInterval0 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1581     curInterval1 = valueProducer.mCurrentSlicedBucket.begin()->second[1];
   1582     EXPECT_EQ(true, curInterval0.hasBase);
   1583     EXPECT_EQ(15, curInterval0.base.long_value);
   1584     EXPECT_EQ(true, curInterval0.hasValue);
   1585     EXPECT_EQ(true, curInterval1.hasBase);
   1586     EXPECT_EQ(25, curInterval1.base.long_value);
   1587     EXPECT_EQ(true, curInterval1.hasValue);
   1588 
   1589     shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
   1590     event4->write(1);
   1591     event4->write(15);
   1592     event4->write(29);
   1593     event4->init();
   1594     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
   1595     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
   1596     curInterval0 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
   1597     curInterval1 = valueProducer.mCurrentSlicedBucket.begin()->second[1];
   1598     EXPECT_EQ(true, curInterval0.hasBase);
   1599     EXPECT_EQ(15, curInterval0.base.long_value);
   1600     EXPECT_EQ(true, curInterval0.hasValue);
   1601     EXPECT_EQ(true, curInterval1.hasBase);
   1602     EXPECT_EQ(29, curInterval1.base.long_value);
   1603     EXPECT_EQ(true, curInterval1.hasValue);
   1604 
   1605     valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
   1606 
   1607     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
   1608     EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
   1609     EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
   1610     EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
   1611 
   1612     EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
   1613     EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
   1614     EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
   1615     EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
   1616     EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
   1617 
   1618     EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
   1619     EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
   1620     EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
   1621 }
   1622 
   1623 /*
   1624  * Tests zero default base.
   1625  */
   1626 TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
   1627     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1628     metric.mutable_dimensions_in_what()->set_field(tagId);
   1629     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   1630     metric.set_use_zero_default_base(true);
   1631 
   1632     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1633     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1634             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1635                 data->clear();
   1636                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   1637                 event->write(1);
   1638                 event->write(3);
   1639                 event->init();
   1640                 data->push_back(event);
   1641                 return true;
   1642             }));
   1643 
   1644     sp<ValueMetricProducer> valueProducer =
   1645             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   1646 
   1647     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1648     auto iter = valueProducer->mCurrentSlicedBucket.begin();
   1649     auto& interval1 = iter->second[0];
   1650     EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1651     EXPECT_EQ(true, interval1.hasBase);
   1652     EXPECT_EQ(3, interval1.base.long_value);
   1653     EXPECT_EQ(false, interval1.hasValue);
   1654     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   1655     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1656     vector<shared_ptr<LogEvent>> allData;
   1657 
   1658     allData.clear();
   1659     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1660     event1->write(2);
   1661     event1->write(4);
   1662     event1->init();
   1663     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1664     event2->write(1);
   1665     event2->write(11);
   1666     event2->init();
   1667     allData.push_back(event1);
   1668     allData.push_back(event2);
   1669 
   1670     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   1671     EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
   1672     EXPECT_EQ(true, interval1.hasBase);
   1673     EXPECT_EQ(11, interval1.base.long_value);
   1674     EXPECT_EQ(false, interval1.hasValue);
   1675     EXPECT_EQ(8, interval1.value.long_value);
   1676 
   1677     auto it = valueProducer->mCurrentSlicedBucket.begin();
   1678     for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
   1679         if (it != iter) {
   1680             break;
   1681         }
   1682     }
   1683     EXPECT_TRUE(it != iter);
   1684     auto& interval2 = it->second[0];
   1685     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1686     EXPECT_EQ(true, interval2.hasBase);
   1687     EXPECT_EQ(4, interval2.base.long_value);
   1688     EXPECT_EQ(false, interval2.hasValue);
   1689     EXPECT_EQ(4, interval2.value.long_value);
   1690 
   1691     EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
   1692     auto iterator = valueProducer->mPastBuckets.begin();
   1693     EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
   1694     EXPECT_EQ(8, iterator->second[0].values[0].long_value);
   1695     iterator++;
   1696     EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
   1697     EXPECT_EQ(4, iterator->second[0].values[0].long_value);
   1698 }
   1699 
   1700 /*
   1701  * Tests using zero default base with failed pull.
   1702  */
   1703 TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
   1704     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1705     metric.mutable_dimensions_in_what()->set_field(tagId);
   1706     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   1707     metric.set_use_zero_default_base(true);
   1708 
   1709     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1710     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1711             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1712                 data->clear();
   1713                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   1714                 event->write(1);
   1715                 event->write(3);
   1716                 event->init();
   1717                 data->push_back(event);
   1718                 return true;
   1719             }));
   1720 
   1721     sp<ValueMetricProducer> valueProducer =
   1722             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   1723 
   1724     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1725     auto iter = valueProducer->mCurrentSlicedBucket.begin();
   1726     auto& interval1 = iter->second[0];
   1727     EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1728     EXPECT_EQ(true, interval1.hasBase);
   1729     EXPECT_EQ(3, interval1.base.long_value);
   1730     EXPECT_EQ(false, interval1.hasValue);
   1731     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   1732     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1733     vector<shared_ptr<LogEvent>> allData;
   1734 
   1735     allData.clear();
   1736     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1737     event1->write(2);
   1738     event1->write(4);
   1739     event1->init();
   1740     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1741     event2->write(1);
   1742     event2->write(11);
   1743     event2->init();
   1744     allData.push_back(event1);
   1745     allData.push_back(event2);
   1746 
   1747     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   1748     EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
   1749     EXPECT_EQ(true, interval1.hasBase);
   1750     EXPECT_EQ(11, interval1.base.long_value);
   1751     EXPECT_EQ(false, interval1.hasValue);
   1752     EXPECT_EQ(8, interval1.value.long_value);
   1753 
   1754     auto it = valueProducer->mCurrentSlicedBucket.begin();
   1755     for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
   1756         if (it != iter) {
   1757             break;
   1758         }
   1759     }
   1760     EXPECT_TRUE(it != iter);
   1761     auto& interval2 = it->second[0];
   1762     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1763     EXPECT_EQ(true, interval2.hasBase);
   1764     EXPECT_EQ(4, interval2.base.long_value);
   1765     EXPECT_EQ(false, interval2.hasValue);
   1766     EXPECT_EQ(4, interval2.value.long_value);
   1767     EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
   1768 
   1769     // next pull somehow did not happen, skip to end of bucket 3
   1770     allData.clear();
   1771     event1 = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
   1772     event1->write(2);
   1773     event1->write(5);
   1774     event1->init();
   1775     allData.push_back(event1);
   1776     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
   1777 
   1778     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1779     EXPECT_EQ(true, interval2.hasBase);
   1780     EXPECT_EQ(5, interval2.base.long_value);
   1781     EXPECT_EQ(false, interval2.hasValue);
   1782     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   1783     EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
   1784 
   1785     allData.clear();
   1786     event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
   1787     event1->write(2);
   1788     event1->write(13);
   1789     event1->init();
   1790     allData.push_back(event1);
   1791     event2 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
   1792     event2->write(1);
   1793     event2->write(5);
   1794     event2->init();
   1795     allData.push_back(event2);
   1796     valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
   1797 
   1798     EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
   1799     auto it1 = std::next(valueProducer->mCurrentSlicedBucket.begin())->second[0];
   1800     EXPECT_EQ(true, it1.hasBase);
   1801     EXPECT_EQ(13, it1.base.long_value);
   1802     EXPECT_EQ(false, it1.hasValue);
   1803     EXPECT_EQ(8, it1.value.long_value);
   1804     auto it2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1805     EXPECT_EQ(true, it2.hasBase);
   1806     EXPECT_EQ(5, it2.base.long_value);
   1807     EXPECT_EQ(false, it2.hasValue);
   1808     EXPECT_EQ(5, it2.value.long_value);
   1809     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   1810     EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
   1811 }
   1812 
   1813 /*
   1814  * Tests trim unused dimension key if no new data is seen in an entire bucket.
   1815  */
   1816 TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
   1817     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   1818     metric.mutable_dimensions_in_what()->set_field(tagId);
   1819     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   1820 
   1821     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1822     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1823             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1824                 data->clear();
   1825                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   1826                 event->write(1);
   1827                 event->write(3);
   1828                 event->init();
   1829                 data->push_back(event);
   1830                 return true;
   1831             }));
   1832 
   1833     sp<ValueMetricProducer> valueProducer =
   1834             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   1835 
   1836     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1837     auto iter = valueProducer->mCurrentSlicedBucket.begin();
   1838     auto& interval1 = iter->second[0];
   1839     EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1840     EXPECT_EQ(true, interval1.hasBase);
   1841     EXPECT_EQ(3, interval1.base.long_value);
   1842     EXPECT_EQ(false, interval1.hasValue);
   1843     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1844     vector<shared_ptr<LogEvent>> allData;
   1845 
   1846     allData.clear();
   1847     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1848     event1->write(2);
   1849     event1->write(4);
   1850     event1->init();
   1851     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   1852     event2->write(1);
   1853     event2->write(11);
   1854     event2->init();
   1855     allData.push_back(event1);
   1856     allData.push_back(event2);
   1857 
   1858     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   1859     EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
   1860     EXPECT_EQ(true, interval1.hasBase);
   1861     EXPECT_EQ(11, interval1.base.long_value);
   1862     EXPECT_EQ(false, interval1.hasValue);
   1863     EXPECT_EQ(8, interval1.value.long_value);
   1864     EXPECT_FALSE(interval1.seenNewData);
   1865     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs});
   1866 
   1867     auto it = valueProducer->mCurrentSlicedBucket.begin();
   1868     for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
   1869         if (it != iter) {
   1870             break;
   1871         }
   1872     }
   1873     EXPECT_TRUE(it != iter);
   1874     auto& interval2 = it->second[0];
   1875     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1876     EXPECT_EQ(true, interval2.hasBase);
   1877     EXPECT_EQ(4, interval2.base.long_value);
   1878     EXPECT_EQ(false, interval2.hasValue);
   1879     EXPECT_FALSE(interval2.seenNewData);
   1880     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs});
   1881 
   1882     // next pull somehow did not happen, skip to end of bucket 3
   1883     allData.clear();
   1884     event1 = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
   1885     event1->write(2);
   1886     event1->write(5);
   1887     event1->init();
   1888     allData.push_back(event1);
   1889     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
   1890 	// Only one interval left. One was trimmed.
   1891     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1892     interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1893     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
   1894     EXPECT_EQ(true, interval2.hasBase);
   1895     EXPECT_EQ(5, interval2.base.long_value);
   1896     EXPECT_EQ(false, interval2.hasValue);
   1897     EXPECT_FALSE(interval2.seenNewData);
   1898     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs});
   1899 
   1900     allData.clear();
   1901     event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
   1902     event1->write(2);
   1903     event1->write(14);
   1904     event1->init();
   1905     allData.push_back(event1);
   1906     valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
   1907 
   1908     interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1909     EXPECT_EQ(true, interval2.hasBase);
   1910     EXPECT_EQ(14, interval2.base.long_value);
   1911     EXPECT_EQ(false, interval2.hasValue);
   1912     EXPECT_FALSE(interval2.seenNewData);
   1913     ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
   1914     auto iterator = valueProducer->mPastBuckets.begin();
   1915     EXPECT_EQ(9, iterator->second[0].values[0].long_value);
   1916     EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
   1917     iterator++;
   1918     EXPECT_EQ(8, iterator->second[0].values[0].long_value);
   1919     EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
   1920 }
   1921 
   1922 TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
   1923     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   1924 
   1925     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1926     // Used by onConditionChanged.
   1927     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1928             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1929                 data->clear();
   1930                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   1931                 event->write(tagId);
   1932                 event->write(100);
   1933                 event->init();
   1934                 data->push_back(event);
   1935                 return true;
   1936             }));
   1937 
   1938     sp<ValueMetricProducer> valueProducer =
   1939             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   1940 
   1941     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   1942     // has one slice
   1943     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1944     ValueMetricProducer::Interval& curInterval =
   1945             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1946     EXPECT_EQ(true, curInterval.hasBase);
   1947     EXPECT_EQ(100, curInterval.base.long_value);
   1948     EXPECT_EQ(false, curInterval.hasValue);
   1949 
   1950     vector<shared_ptr<LogEvent>> allData;
   1951     valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
   1952     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1953     EXPECT_EQ(false, curInterval.hasBase);
   1954     EXPECT_EQ(false, curInterval.hasValue);
   1955     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
   1956 }
   1957 
   1958 TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
   1959     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   1960 
   1961     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   1962     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   1963             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   1964                 data->clear();
   1965                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   1966                 event->write(tagId);
   1967                 event->write(100);
   1968                 event->init();
   1969                 data->push_back(event);
   1970                 return true;
   1971             }))
   1972             .WillOnce(Return(false));
   1973 
   1974     sp<ValueMetricProducer> valueProducer =
   1975             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   1976 
   1977     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   1978 
   1979     // has one slice
   1980     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1981     ValueMetricProducer::Interval& curInterval =
   1982             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   1983     EXPECT_EQ(true, curInterval.hasBase);
   1984     EXPECT_EQ(100, curInterval.base.long_value);
   1985     EXPECT_EQ(false, curInterval.hasValue);
   1986     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   1987 
   1988     valueProducer->onConditionChanged(false, bucketStartTimeNs + 20);
   1989 
   1990     // has one slice
   1991     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   1992     EXPECT_EQ(false, curInterval.hasValue);
   1993     EXPECT_EQ(false, curInterval.hasBase);
   1994     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
   1995 }
   1996 
   1997 TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
   1998     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   1999 
   2000     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2001     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2002             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2003                 data->clear();
   2004                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2005                 event->write(tagId);
   2006                 event->write(50);
   2007                 event->init();
   2008                 data->push_back(event);
   2009                 return false;
   2010             }))
   2011             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2012                 data->clear();
   2013                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2014                 event->write(tagId);
   2015                 event->write(100);
   2016                 event->init();
   2017                 data->push_back(event);
   2018                 return true;
   2019             }));
   2020 
   2021     sp<ValueMetricProducer> valueProducer =
   2022             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2023 
   2024     // Don't directly set mCondition; the real code never does that. Go through regular code path
   2025     // to avoid unexpected behaviors.
   2026     // valueProducer->mCondition = ConditionState::kTrue;
   2027     valueProducer->onConditionChanged(true, bucketStartTimeNs);
   2028 
   2029     EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2030 
   2031     valueProducer->onConditionChanged(false, bucketStartTimeNs + 1);
   2032     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2033     ValueMetricProducer::Interval& curInterval =
   2034             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2035     EXPECT_EQ(false, curInterval.hasBase);
   2036     EXPECT_EQ(false, curInterval.hasValue);
   2037     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
   2038 }
   2039 
   2040 TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
   2041     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2042     metric.set_condition(StringToId("SCREEN_ON"));
   2043     metric.set_max_pull_delay_sec(0);
   2044 
   2045     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2046     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2047             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2048                 data->clear();
   2049                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2050                 event->write(tagId);
   2051                 event->write(120);
   2052                 event->init();
   2053                 data->push_back(event);
   2054                 return true;
   2055             }));
   2056 
   2057     sp<ValueMetricProducer> valueProducer =
   2058             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2059 
   2060     valueProducer->mCondition = ConditionState::kFalse;
   2061 
   2062     // Max delay is set to 0 so pull will exceed max delay.
   2063     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
   2064     EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2065 }
   2066 
   2067 TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
   2068     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2069 
   2070     UidMap uidMap;
   2071     SimpleAtomMatcher atomMatcher;
   2072     atomMatcher.set_atom_id(tagId);
   2073     sp<EventMatcherWizard> eventMatcherWizard =
   2074             new EventMatcherWizard({new SimpleLogMatchingTracker(
   2075                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   2076     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   2077     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2078     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
   2079     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
   2080 
   2081     ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
   2082                                       eventMatcherWizard, tagId, bucket2StartTimeNs,
   2083                                       bucket2StartTimeNs, pullerManager);
   2084     valueProducer.prepareFirstBucket();
   2085     valueProducer.mCondition = ConditionState::kFalse;
   2086 
   2087     // Event should be skipped since it is from previous bucket.
   2088     // Pull should not be called.
   2089     valueProducer.onConditionChanged(true, bucketStartTimeNs);
   2090     EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
   2091 }
   2092 
   2093 TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
   2094     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2095 
   2096     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2097     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2098             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2099                 data->clear();
   2100                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2101                 event->write(tagId);
   2102                 event->write(100);
   2103                 event->init();
   2104                 data->push_back(event);
   2105                 return true;
   2106             }));
   2107 
   2108     sp<ValueMetricProducer> valueProducer =
   2109             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2110 
   2111     valueProducer->mCondition = ConditionState::kFalse;
   2112     valueProducer->mHasGlobalBase = false;
   2113 
   2114     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
   2115     valueProducer->mHasGlobalBase = true;
   2116     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2117     ValueMetricProducer::Interval& curInterval =
   2118             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2119     EXPECT_EQ(true, curInterval.hasBase);
   2120     EXPECT_EQ(100, curInterval.base.long_value);
   2121     EXPECT_EQ(false, curInterval.hasValue);
   2122     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2123 }
   2124 
   2125 TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) {
   2126     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2127 
   2128     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2129     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2130             // First onConditionChanged
   2131             .WillOnce(Return(false))
   2132             // Second onConditionChanged
   2133             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2134                 data->clear();
   2135                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2136                 event->write(tagId);
   2137                 event->write(130);
   2138                 event->init();
   2139                 data->push_back(event);
   2140                 return true;
   2141             }));
   2142 
   2143     sp<ValueMetricProducer> valueProducer =
   2144             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2145 
   2146     valueProducer->mCondition = ConditionState::kTrue;
   2147 
   2148     // Bucket start.
   2149     vector<shared_ptr<LogEvent>> allData;
   2150     allData.clear();
   2151     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2152     event->write(1);
   2153     event->write(110);
   2154     event->init();
   2155     allData.push_back(event);
   2156     valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
   2157 
   2158     // This will fail and should invalidate the whole bucket since we do not have all the data
   2159     // needed to compute the metric value when the screen was on.
   2160     valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
   2161     valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
   2162 
   2163     // Bucket end.
   2164     allData.clear();
   2165     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2166     event2->write(1);
   2167     event2->write(140);
   2168     event2->init();
   2169     allData.push_back(event2);
   2170     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2171 
   2172     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
   2173 
   2174     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   2175     // Contains base from last pull which was successful.
   2176     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2177     ValueMetricProducer::Interval& curInterval =
   2178             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2179     EXPECT_EQ(true, curInterval.hasBase);
   2180     EXPECT_EQ(140, curInterval.base.long_value);
   2181     EXPECT_EQ(false, curInterval.hasValue);
   2182     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2183 }
   2184 
   2185 TEST(ValueMetricProducerTest, TestInvalidBucketWhenGuardRailHit) {
   2186     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2187     metric.mutable_dimensions_in_what()->set_field(tagId);
   2188     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   2189     metric.set_condition(StringToId("SCREEN_ON"));
   2190 
   2191     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2192     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2193             // First onConditionChanged
   2194             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2195                 for (int i = 0; i < 2000; i++) {
   2196                     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2197                     event->write(i);
   2198                     event->write(i);
   2199                     event->init();
   2200                     data->push_back(event);
   2201                 }
   2202                 return true;
   2203             }));
   2204 
   2205     sp<ValueMetricProducer> valueProducer =
   2206             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2207     valueProducer->mCondition = ConditionState::kFalse;
   2208 
   2209     valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
   2210     EXPECT_EQ(true, valueProducer->mCurrentBucketIsInvalid);
   2211     EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2212 }
   2213 
   2214 TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed) {
   2215     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2216 
   2217     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2218     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2219             // First onConditionChanged
   2220             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2221                 data->clear();
   2222                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2223                 event->write(tagId);
   2224                 event->write(120);
   2225                 event->init();
   2226                 data->push_back(event);
   2227                 return true;
   2228             }))
   2229             // Second onConditionChanged
   2230             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2231                 data->clear();
   2232                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2233                 event->write(tagId);
   2234                 event->write(130);
   2235                 event->init();
   2236                 data->push_back(event);
   2237                 return true;
   2238             }));
   2239 
   2240     sp<ValueMetricProducer> valueProducer =
   2241             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2242 
   2243     valueProducer->mCondition = ConditionState::kTrue;
   2244 
   2245     // Bucket start.
   2246     vector<shared_ptr<LogEvent>> allData;
   2247     allData.clear();
   2248     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2249     event->write(1);
   2250     event->write(110);
   2251     event->init();
   2252     allData.push_back(event);
   2253     valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs);
   2254 
   2255     valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
   2256     valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
   2257 
   2258     // Bucket end.
   2259     allData.clear();
   2260     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2261     event2->write(1);
   2262     event2->write(140);
   2263     event2->init();
   2264     allData.push_back(event2);
   2265     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2266 
   2267     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
   2268 
   2269     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   2270     // Contains base from last pull which was successful.
   2271     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2272     ValueMetricProducer::Interval& curInterval =
   2273             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2274     EXPECT_EQ(true, curInterval.hasBase);
   2275     EXPECT_EQ(140, curInterval.base.long_value);
   2276     EXPECT_EQ(false, curInterval.hasValue);
   2277     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2278 }
   2279 
   2280 TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed) {
   2281     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2282 
   2283     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2284     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2285             // First onConditionChanged
   2286             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2287                 data->clear();
   2288                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2289                 event->write(tagId);
   2290                 event->write(120);
   2291                 event->init();
   2292                 data->push_back(event);
   2293                 return true;
   2294             }))
   2295             // Second onConditionChanged
   2296             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2297                 data->clear();
   2298                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
   2299                 event->write(tagId);
   2300                 event->write(130);
   2301                 event->init();
   2302                 data->push_back(event);
   2303                 return true;
   2304             }));
   2305 
   2306     sp<ValueMetricProducer> valueProducer =
   2307             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2308 
   2309     valueProducer->mCondition = ConditionState::kTrue;
   2310 
   2311     // Bucket start.
   2312     vector<shared_ptr<LogEvent>> allData;
   2313     allData.clear();
   2314     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
   2315     event->write(1);
   2316     event->write(110);
   2317     event->init();
   2318     allData.push_back(event);
   2319     valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
   2320 
   2321     // This will fail and should invalidate the whole bucket since we do not have all the data
   2322     // needed to compute the metric value when the screen was on.
   2323     valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
   2324     valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
   2325 
   2326     // Bucket end.
   2327     allData.clear();
   2328     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2329     event2->write(1);
   2330     event2->write(140);
   2331     event2->init();
   2332     allData.push_back(event2);
   2333     valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
   2334 
   2335     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
   2336 
   2337     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   2338     // Last pull failed so based has been reset.
   2339     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2340     ValueMetricProducer::Interval& curInterval =
   2341             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2342     EXPECT_EQ(false, curInterval.hasBase);
   2343     EXPECT_EQ(false, curInterval.hasValue);
   2344     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
   2345 }
   2346 
   2347 TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
   2348     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2349     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2350     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2351             // Start bucket.
   2352             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2353                 data->clear();
   2354                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2355                 event->write(tagId);
   2356                 event->write(3);
   2357                 event->init();
   2358                 data->push_back(event);
   2359                 return true;
   2360             }));
   2361 
   2362     sp<ValueMetricProducer> valueProducer =
   2363             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2364 
   2365     // Bucket 2 start.
   2366     vector<shared_ptr<LogEvent>> allData;
   2367     allData.clear();
   2368     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2369     event->write(tagId);
   2370     event->write(110);
   2371     event->init();
   2372     allData.push_back(event);
   2373     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2374     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2375     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
   2376 
   2377     // Bucket 3 empty.
   2378     allData.clear();
   2379     shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
   2380     event2->init();
   2381     allData.push_back(event2);
   2382     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
   2383     // Data has been trimmed.
   2384     EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2385     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
   2386 }
   2387 
   2388 TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
   2389     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2390 
   2391     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2392     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2393             // First onConditionChanged
   2394             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2395                 data->clear();
   2396                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2397                 event->write(tagId);
   2398                 event->write(3);
   2399                 event->init();
   2400                 data->push_back(event);
   2401                 return true;
   2402             }))
   2403             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2404                 data->clear();
   2405                 return true;
   2406             }));
   2407 
   2408     sp<ValueMetricProducer> valueProducer =
   2409             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2410 
   2411     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
   2412     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2413     ValueMetricProducer::Interval& curInterval =
   2414             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2415     EXPECT_EQ(true, curInterval.hasBase);
   2416     EXPECT_EQ(false, curInterval.hasValue);
   2417     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2418 
   2419     // Empty pull.
   2420     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
   2421     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2422     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2423     EXPECT_EQ(false, curInterval.hasBase);
   2424     EXPECT_EQ(false, curInterval.hasValue);
   2425     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
   2426 }
   2427 
   2428 TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
   2429     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2430 
   2431     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2432     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2433             // First onConditionChanged
   2434             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2435                 data->clear();
   2436                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2437                 event->write(tagId);
   2438                 event->write(1);
   2439                 event->init();
   2440                 data->push_back(event);
   2441                 return true;
   2442             }))
   2443             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2444                 data->clear();
   2445                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2446                 event->write(tagId);
   2447                 event->write(2);
   2448                 event->init();
   2449                 data->push_back(event);
   2450                 return true;
   2451             }))
   2452             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2453                 data->clear();
   2454                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2455                 event->write(tagId);
   2456                 event->write(5);
   2457                 event->init();
   2458                 data->push_back(event);
   2459                 return true;
   2460             }));
   2461 
   2462     sp<ValueMetricProducer> valueProducer =
   2463             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2464 
   2465     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
   2466     valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
   2467     valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
   2468     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2469     ValueMetricProducer::Interval& curInterval =
   2470             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2471     EXPECT_EQ(true, curInterval.hasBase);
   2472     EXPECT_EQ(true, curInterval.hasValue);
   2473     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2474 
   2475     // End of bucket
   2476     vector<shared_ptr<LogEvent>> allData;
   2477     allData.clear();
   2478     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2479     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2480     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2481     // Data is empty, base should be reset.
   2482     EXPECT_EQ(false, curInterval.hasBase);
   2483     EXPECT_EQ(5, curInterval.base.long_value);
   2484     EXPECT_EQ(false, curInterval.hasValue);
   2485     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2486 
   2487     EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
   2488     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1});
   2489 }
   2490 
   2491 TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
   2492     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2493     metric.mutable_dimensions_in_what()->set_field(tagId);
   2494     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   2495     metric.set_condition(StringToId("SCREEN_ON"));
   2496 
   2497     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2498     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2499             // First onConditionChanged
   2500             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2501                 data->clear();
   2502                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2503                 event->write(tagId);
   2504                 event->write(1);
   2505                 event->write(1);
   2506                 event->init();
   2507                 data->push_back(event);
   2508                 return true;
   2509             }));
   2510 
   2511     sp<ValueMetricProducer> valueProducer =
   2512             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2513 
   2514     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
   2515     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2516 
   2517     // End of bucket
   2518     vector<shared_ptr<LogEvent>> allData;
   2519     allData.clear();
   2520     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2521     event->write(2);
   2522     event->write(2);
   2523     event->init();
   2524     allData.push_back(event);
   2525     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2526 
   2527     // Key 1 should be reset since in not present in the most pull.
   2528     EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
   2529     auto iterator = valueProducer->mCurrentSlicedBucket.begin();
   2530     EXPECT_EQ(true, iterator->second[0].hasBase);
   2531     EXPECT_EQ(2, iterator->second[0].base.long_value);
   2532     EXPECT_EQ(false, iterator->second[0].hasValue);
   2533     iterator++;
   2534     EXPECT_EQ(false, iterator->second[0].hasBase);
   2535     EXPECT_EQ(1, iterator->second[0].base.long_value);
   2536     EXPECT_EQ(false, iterator->second[0].hasValue);
   2537 
   2538     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
   2539 }
   2540 
   2541 TEST(ValueMetricProducerTest, TestBucketIncludingUnknownConditionIsInvalid) {
   2542     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2543     metric.mutable_dimensions_in_what()->set_field(tagId);
   2544     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
   2545     metric.set_condition(StringToId("SCREEN_ON"));
   2546 
   2547     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2548     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2549             // Second onConditionChanged.
   2550             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2551                 data->clear();
   2552                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2553                 event->write(tagId);
   2554                 event->write(2);
   2555                 event->write(2);
   2556                 event->init();
   2557                 data->push_back(event);
   2558                 return true;
   2559             }));
   2560 
   2561     sp<ValueMetricProducer> valueProducer =
   2562             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2563     valueProducer->mCondition = ConditionState::kUnknown;
   2564 
   2565     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
   2566     valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
   2567 
   2568     // End of bucket
   2569     vector<shared_ptr<LogEvent>> allData;
   2570     allData.clear();
   2571     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2572     event->write(4);
   2573     event->write(4);
   2574     event->init();
   2575     allData.push_back(event);
   2576     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2577 
   2578     // Bucket is incomplete so it is mark as invalid, however the base is fine since the last pull
   2579     // succeeded.
   2580     EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
   2581 }
   2582 
   2583 TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) {
   2584     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2585 
   2586     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2587     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2588             // Initialization.
   2589             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2590                 data->clear();
   2591                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
   2592                 return true;
   2593             }))
   2594             // notifyAppUpgrade.
   2595             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2596                 data->clear();
   2597                 data->push_back(ValueMetricProducerTestHelper::createEvent(
   2598                         bucketStartTimeNs + bucketSizeNs / 2, 10));
   2599                 return true;
   2600             }));
   2601     sp<ValueMetricProducer> valueProducer =
   2602             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2603     ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
   2604 
   2605     valueProducer->notifyAppUpgrade(bucketStartTimeNs + bucketSizeNs / 2, "com.foo", 10000, 1);
   2606     ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
   2607 
   2608     vector<shared_ptr<LogEvent>> allData;
   2609     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 1, 4));
   2610     valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
   2611     ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
   2612 }
   2613 
   2614 TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
   2615     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2616     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2617     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2618             // Second onConditionChanged.
   2619             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2620                 data->clear();
   2621                 data->push_back(
   2622                         ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 10, 5));
   2623                 return true;
   2624             }))
   2625             // Third onConditionChanged.
   2626             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2627                 data->clear();
   2628                 data->push_back(
   2629                         ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs + 10, 7));
   2630                 return true;
   2631             }));
   2632 
   2633     sp<ValueMetricProducer> valueProducer =
   2634             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2635     valueProducer->mCondition = ConditionState::kUnknown;
   2636 
   2637     valueProducer->onConditionChanged(false, bucketStartTimeNs);
   2638     ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2639 
   2640     // End of first bucket
   2641     vector<shared_ptr<LogEvent>> allData;
   2642     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 4));
   2643     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
   2644     ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
   2645 
   2646     valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
   2647     ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2648     auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2649     EXPECT_EQ(true, curInterval.hasBase);
   2650     EXPECT_EQ(5, curInterval.base.long_value);
   2651     EXPECT_EQ(false, curInterval.hasValue);
   2652 
   2653     valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
   2654 
   2655     // Bucket should have been completed.
   2656     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10});
   2657 }
   2658 
   2659 TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
   2660     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2661     metric.set_use_diff(false);
   2662 
   2663     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2664     sp<ValueMetricProducer> valueProducer =
   2665             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2666 
   2667     vector<shared_ptr<LogEvent>> allData;
   2668     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
   2669     valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
   2670 
   2671     allData.clear();
   2672     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
   2673     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2674 
   2675     // Bucket should have been completed.
   2676     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs});
   2677 }
   2678 
   2679 TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
   2680     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2681 
   2682     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2683     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2684             // Initialization.
   2685             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2686                 data->clear();
   2687                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
   2688                 return true;
   2689             }));
   2690 
   2691     sp<ValueMetricProducer> valueProducer =
   2692             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2693 
   2694     vector<shared_ptr<LogEvent>> allData;
   2695     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 30, 10));
   2696     valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
   2697 
   2698     allData.clear();
   2699     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
   2700     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2701 
   2702     // Bucket should have been completed.
   2703     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs});
   2704 }
   2705 
   2706 TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) {
   2707     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2708 
   2709     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2710     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2711             // Initialization.
   2712             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2713                 data->clear();
   2714                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
   2715                 return true;
   2716             }))
   2717             // notifyAppUpgrade.
   2718             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2719                 data->clear();
   2720                 data->push_back(
   2721                         ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 2, 10));
   2722                 return true;
   2723             }));
   2724 
   2725     sp<ValueMetricProducer> valueProducer =
   2726             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2727 
   2728     valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
   2729 
   2730     // Bucket should have been completed.
   2731     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs});
   2732 }
   2733 
   2734 TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
   2735     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2736 
   2737     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2738     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2739             // First on condition changed.
   2740             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2741                 data->clear();
   2742                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
   2743                 return true;
   2744             }))
   2745             // Second on condition changed.
   2746             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2747                 data->clear();
   2748                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 3));
   2749                 return true;
   2750             }));
   2751 
   2752     sp<ValueMetricProducer> valueProducer =
   2753             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2754 
   2755     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   2756     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
   2757     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
   2758 
   2759     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   2760     auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   2761     EXPECT_EQ(true, curInterval.hasValue);
   2762     EXPECT_EQ(2, curInterval.value.long_value);
   2763 
   2764     vector<shared_ptr<LogEvent>> allData;
   2765     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 1, 10));
   2766     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
   2767 
   2768     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2});
   2769 }
   2770 
   2771 TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
   2772     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   2773 
   2774     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2775     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2776             // First condition change.
   2777             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2778                 data->clear();
   2779                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs, 1));
   2780                 return true;
   2781             }))
   2782             // 2nd condition change.
   2783             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2784                 data->clear();
   2785                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
   2786                 return true;
   2787             }))
   2788             // 3rd condition change.
   2789             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2790                 data->clear();
   2791                 data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
   2792                 return true;
   2793             }));
   2794 
   2795     sp<ValueMetricProducer> valueProducer =
   2796             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   2797     valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
   2798 
   2799     vector<shared_ptr<LogEvent>> allData;
   2800     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucketStartTimeNs + 3, 10));
   2801     valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
   2802 
   2803     allData.clear();
   2804     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 20));
   2805     valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
   2806 
   2807     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
   2808     valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
   2809 
   2810     allData.clear();
   2811     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket3StartTimeNs, 30));
   2812     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2813 
   2814     // There was not global base available so all buckets are invalid.
   2815     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
   2816 }
   2817 
   2818 static StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
   2819     vector<uint8_t> bytes;
   2820     bytes.resize(proto->size());
   2821     size_t pos = 0;
   2822     sp<ProtoReader> reader = proto->data();
   2823     while (reader->readBuffer() != NULL) {
   2824         size_t toRead = reader->currentToRead();
   2825         std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
   2826         pos += toRead;
   2827         reader->move(toRead);
   2828     }
   2829 
   2830     StatsLogReport report;
   2831     report.ParseFromArray(bytes.data(), bytes.size());
   2832     return report;
   2833 }
   2834 
   2835 TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
   2836     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2837 
   2838     UidMap uidMap;
   2839     SimpleAtomMatcher atomMatcher;
   2840     atomMatcher.set_atom_id(tagId);
   2841     sp<EventMatcherWizard> eventMatcherWizard =
   2842             new EventMatcherWizard({new SimpleLogMatchingTracker(
   2843                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   2844     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   2845     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2846     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
   2847     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
   2848 
   2849     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2850             // Initial pull.
   2851             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2852                 data->clear();
   2853                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2854                 event->write(tagId);
   2855                 event->write(1);
   2856                 event->write(1);
   2857                 event->init();
   2858                 data->push_back(event);
   2859                 return true;
   2860             }));
   2861 
   2862     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   2863                                       eventMatcherWizard, tagId, bucketStartTimeNs,
   2864                                       bucketStartTimeNs, pullerManager);
   2865     valueProducer.prepareFirstBucket();
   2866 
   2867     ProtoOutputStream output;
   2868     std::set<string> strSet;
   2869     valueProducer.onDumpReport(bucketStartTimeNs + 10,
   2870                                true /* include recent buckets */, true,
   2871                                FAST, &strSet, &output);
   2872 
   2873     StatsLogReport report = outputStreamToProto(&output);
   2874     // Bucket is invalid since we did not pull when dump report was called.
   2875     EXPECT_EQ(0, report.value_metrics().data_size());
   2876 }
   2877 
   2878 TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
   2879     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2880 
   2881     UidMap uidMap;
   2882     SimpleAtomMatcher atomMatcher;
   2883     atomMatcher.set_atom_id(tagId);
   2884     sp<EventMatcherWizard> eventMatcherWizard =
   2885             new EventMatcherWizard({new SimpleLogMatchingTracker(
   2886                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   2887     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   2888     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2889     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
   2890     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
   2891 
   2892     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2893             // Initial pull.
   2894             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2895                 data->clear();
   2896                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2897                 event->write(tagId);
   2898                 event->write(1);
   2899                 event->write(1);
   2900                 event->init();
   2901                 data->push_back(event);
   2902                 return true;
   2903             }));
   2904 
   2905     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   2906                                       eventMatcherWizard, tagId, bucketStartTimeNs,
   2907                                       bucketStartTimeNs, pullerManager);
   2908     valueProducer.prepareFirstBucket();
   2909 
   2910     vector<shared_ptr<LogEvent>> allData;
   2911     allData.clear();
   2912     shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
   2913     event->write(tagId);
   2914     event->write(2);
   2915     event->write(2);
   2916     event->init();
   2917     allData.push_back(event);
   2918     valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   2919 
   2920     ProtoOutputStream output;
   2921     std::set<string> strSet;
   2922     valueProducer.onDumpReport(bucket4StartTimeNs,
   2923                                false /* include recent buckets */, true,
   2924                                FAST, &strSet, &output);
   2925 
   2926     StatsLogReport report = outputStreamToProto(&output);
   2927     // Previous bucket is part of the report.
   2928     EXPECT_EQ(1, report.value_metrics().data_size());
   2929     EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
   2930 }
   2931 
   2932 TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
   2933     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2934 
   2935     UidMap uidMap;
   2936     SimpleAtomMatcher atomMatcher;
   2937     atomMatcher.set_atom_id(tagId);
   2938     sp<EventMatcherWizard> eventMatcherWizard =
   2939             new EventMatcherWizard({new SimpleLogMatchingTracker(
   2940                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
   2941     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
   2942     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2943     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
   2944     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
   2945 
   2946     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   2947             // Initial pull.
   2948             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2949                 data->clear();
   2950                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
   2951                 event->write(tagId);
   2952                 event->write(1);
   2953                 event->write(1);
   2954                 event->init();
   2955                 data->push_back(event);
   2956                 return true;
   2957             }))
   2958             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   2959                 data->clear();
   2960                 shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
   2961                 event->write(tagId);
   2962                 event->write(3);
   2963                 event->write(3);
   2964                 event->init();
   2965                 data->push_back(event);
   2966                 return true;
   2967             }));
   2968 
   2969     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
   2970                                       eventMatcherWizard, tagId, bucketStartTimeNs,
   2971                                       bucketStartTimeNs, pullerManager);
   2972     valueProducer.prepareFirstBucket();
   2973 
   2974     ProtoOutputStream output;
   2975     std::set<string> strSet;
   2976     valueProducer.onDumpReport(bucketStartTimeNs + 10,
   2977                                true /* include recent buckets */, true,
   2978                                NO_TIME_CONSTRAINTS, &strSet, &output);
   2979 
   2980     StatsLogReport report = outputStreamToProto(&output);
   2981     EXPECT_EQ(1, report.value_metrics().data_size());
   2982     EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size());
   2983     EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
   2984 }
   2985 
   2986 TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
   2987     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
   2988     metric.set_use_diff(false);
   2989 
   2990     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   2991     sp<ValueMetricProducer> valueProducer =
   2992             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
   2993 
   2994     vector<shared_ptr<LogEvent>> allData;
   2995     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 10));
   2996     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
   2997 
   2998     // Bucket should have been completed.
   2999     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs});
   3000 }
   3001 
   3002 TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
   3003     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   3004     metric.set_use_diff(false);
   3005 
   3006     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   3007     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   3008             // condition becomes true
   3009             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   3010                 data->clear();
   3011                 data->push_back(ValueMetricProducerTestHelper::createEvent(
   3012                         bucketStartTimeNs + 30, 10));
   3013                 return true;
   3014             }))
   3015             // condition becomes false
   3016             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   3017                 data->clear();
   3018                 data->push_back(ValueMetricProducerTestHelper::createEvent(
   3019                         bucketStartTimeNs + 50, 20));
   3020                 return true;
   3021             }));
   3022     sp<ValueMetricProducer> valueProducer =
   3023             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   3024     valueProducer->mCondition = ConditionState::kFalse;
   3025 
   3026     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   3027     valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
   3028     // has one slice
   3029     EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
   3030     ValueMetricProducer::Interval curInterval =
   3031             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   3032     EXPECT_EQ(false, curInterval.hasBase);
   3033     EXPECT_EQ(true, curInterval.hasValue);
   3034     EXPECT_EQ(20, curInterval.value.long_value);
   3035 
   3036 
   3037     // Now the alarm is delivered. Condition is off though.
   3038     vector<shared_ptr<LogEvent>> allData;
   3039     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 110));
   3040     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   3041 
   3042     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8});
   3043     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
   3044     EXPECT_EQ(false, curInterval.hasBase);
   3045     EXPECT_EQ(false, curInterval.hasValue);
   3046 }
   3047 
   3048 TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
   3049     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   3050     metric.set_use_diff(false);
   3051 
   3052     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   3053     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   3054             // condition becomes true
   3055             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   3056                 data->clear();
   3057                 data->push_back(ValueMetricProducerTestHelper::createEvent(
   3058                         bucketStartTimeNs + 30, 10));
   3059                 return true;
   3060             }));
   3061     sp<ValueMetricProducer> valueProducer =
   3062             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   3063     valueProducer->mCondition = ConditionState::kFalse;
   3064 
   3065     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   3066 
   3067     // Now the alarm is delivered. Condition is off though.
   3068     vector<shared_ptr<LogEvent>> allData;
   3069     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
   3070     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   3071 
   3072     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8});
   3073     ValueMetricProducer::Interval curInterval =
   3074             valueProducer->mCurrentSlicedBucket.begin()->second[0];
   3075     EXPECT_EQ(false, curInterval.hasBase);
   3076     EXPECT_EQ(false, curInterval.hasValue);
   3077 }
   3078 
   3079 TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
   3080     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   3081     metric.set_use_diff(false);
   3082 
   3083     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   3084     sp<ValueMetricProducer> valueProducer =
   3085             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   3086     valueProducer->mCondition = ConditionState::kFalse;
   3087 
   3088     // Now the alarm is delivered. Condition is off though.
   3089     vector<shared_ptr<LogEvent>> allData;
   3090     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
   3091     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   3092 
   3093     // Condition was always false.
   3094     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
   3095 }
   3096 
   3097 TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
   3098     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
   3099     metric.set_use_diff(false);
   3100 
   3101     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
   3102     EXPECT_CALL(*pullerManager, Pull(tagId, _))
   3103             // condition becomes true
   3104             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
   3105                 data->clear();
   3106                 data->push_back(ValueMetricProducerTestHelper::createEvent(
   3107                         bucketStartTimeNs + 30, 10));
   3108                 return true;
   3109             }))
   3110             .WillOnce(Return(false));
   3111     sp<ValueMetricProducer> valueProducer =
   3112             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
   3113     valueProducer->mCondition = ConditionState::kFalse;
   3114 
   3115     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
   3116     valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
   3117 
   3118     // Now the alarm is delivered. Condition is off though.
   3119     vector<shared_ptr<LogEvent>> allData;
   3120     allData.push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs + 30, 30));
   3121     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
   3122 
   3123     // No buckets, we had a failure.
   3124     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
   3125 }
   3126 
   3127 }  // namespace statsd
   3128 }  // namespace os
   3129 }  // namespace android
   3130 #else
   3131 GTEST_LOG_(INFO) << "This test does nothing.\n";
   3132 #endif
   3133