summaryrefslogtreecommitdiff
path: root/libs/battery/MultiStateCounterTest.cpp
blob: 942d5cadf5a81c084891597095cb8c55ae9ae5f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * Copyright (C) 2021 The Android Open Source Project
 * Android BPF library - public API
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include "MultiStateCounter.h"

namespace android {
namespace battery {

typedef MultiStateCounter<double> DoubleMultiStateCounter;

template <>
bool DoubleMultiStateCounter::delta(const double& previousValue, const double& newValue,
                                    double* outValue) const {
    *outValue = newValue - previousValue;
    return *outValue >= 0;
}

template <>
void DoubleMultiStateCounter::add(double* value1, const double& value2, const uint64_t numerator,
                                  const uint64_t denominator) const {
    if (numerator != denominator) {
        // The caller ensures that denominator != 0
        *value1 += value2 * numerator / denominator;
    } else {
        *value1 += value2;
    }
}

template <>
std::string DoubleMultiStateCounter::valueToString(const double& v) const {
    return std::to_string(v);
}

class MultiStateCounterTest : public testing::Test {};

TEST_F(MultiStateCounterTest, constructor) {
    DoubleMultiStateCounter testCounter(3, 1, 0, 1000);
    testCounter.setState(1, 2000);
    testCounter.updateValue(3.14, 3000);

    EXPECT_DOUBLE_EQ(0, testCounter.getCount(0));
    EXPECT_DOUBLE_EQ(3.14, testCounter.getCount(1));
    EXPECT_DOUBLE_EQ(0, testCounter.getCount(2));
}

TEST_F(MultiStateCounterTest, stateChange) {
    DoubleMultiStateCounter testCounter(3, 1, 0, 0);
    testCounter.setState(2, 1000);
    testCounter.updateValue(6.0, 3000);

    EXPECT_DOUBLE_EQ(0, testCounter.getCount(0));
    EXPECT_DOUBLE_EQ(2.0, testCounter.getCount(1));
    EXPECT_DOUBLE_EQ(4.0, testCounter.getCount(2));
}

TEST_F(MultiStateCounterTest, timeAdjustment_setState) {
    DoubleMultiStateCounter testCounter(3, 1, 0, 0);
    testCounter.setState(2, 2000);

    // Time moves back
    testCounter.setState(1, 1000);
    testCounter.updateValue(6.0, 3000);

    EXPECT_DOUBLE_EQ(0, testCounter.getCount(0));

    // We were in state 1 from 0 to 2000, which was erased because the time moved back.
    // Then from 1000 to 3000, so we expect the count to be 6 * (2000/3000)
    EXPECT_DOUBLE_EQ(4.0, testCounter.getCount(1));

    // No time was effectively accumulated for state 2, because the timestamp moved back
    // while we were in state 2.
    EXPECT_DOUBLE_EQ(0, testCounter.getCount(2));
}

TEST_F(MultiStateCounterTest, timeAdjustment_updateValue) {
    DoubleMultiStateCounter testCounter(1, 0, 0, 0);
    testCounter.updateValue(6.0, 2000);

    // Time moves back. The negative delta from 2000 to 1000 is ignored
    testCounter.updateValue(8.0, 1000);
    testCounter.updateValue(11.0, 3000);

    // The total accumulated count is:
    //  6.0          // For the period 0-2000
    //  +(11.0-8.0)  // For the period 1000-3000
    EXPECT_DOUBLE_EQ(9.0, testCounter.getCount(0));
}

} // namespace battery
} // namespace android