1 /**
2  * Copyright © 2017 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "../record_manager.hpp"
17 #include "names_values.hpp"
18 
19 #include <iostream>
20 
21 #include <gtest/gtest.h>
22 
23 using namespace witherspoon::power::history;
24 
25 /**
26  * Test the linearToInteger function with different
27  * combinations of positive and negative mantissas and
28  * exponents.
29  *
30  * Value = mantissa * 2**exponent
31  */
32 TEST(LinearFormatTest, TestConversions)
33 {
34     // Mantissa > 0, exponent = 0
35     EXPECT_EQ(0, RecordManager::linearToInteger(0));
36     EXPECT_EQ(1, RecordManager::linearToInteger(1));
37     EXPECT_EQ(38, RecordManager::linearToInteger(0x26));
38     EXPECT_EQ(1023, RecordManager::linearToInteger(0x3FF));
39 
40     // Mantissa < 0, exponent = 0
41     EXPECT_EQ(-1, RecordManager::linearToInteger(0x7FF));
42     EXPECT_EQ(-20, RecordManager::linearToInteger(0x7EC));
43     EXPECT_EQ(-769, RecordManager::linearToInteger(0x4FF));
44     EXPECT_EQ(-989, RecordManager::linearToInteger(0x423));
45     EXPECT_EQ(-1024, RecordManager::linearToInteger(0x400));
46 
47     // Mantissa >= 0, exponent > 0
48     // M = 1, E = 2
49     EXPECT_EQ(4, RecordManager::linearToInteger(0x1001));
50 
51     // M = 1000, E = 10
52     EXPECT_EQ(1024000, RecordManager::linearToInteger(0x53E8));
53 
54     // M = 10, E = 15
55     EXPECT_EQ(327680, RecordManager::linearToInteger(0x780A));
56 
57     // Mantissa >= 0, exponent < 0
58     // M = 0, E = -1
59     EXPECT_EQ(0, RecordManager::linearToInteger(0xF800));
60 
61     // M = 100, E = -2
62     EXPECT_EQ(25, RecordManager::linearToInteger(0xF064));
63 
64     // Mantissa < 0, exponent < 0
65     // M = -100, E = -1
66     EXPECT_EQ(-50, RecordManager::linearToInteger(0xFF9C));
67 
68     // M = -1024, E = -7
69     EXPECT_EQ(-8, RecordManager::linearToInteger(0xCC00));
70 }
71 
72 /**
73  * @brief Helper function to create a record buffer
74  *
75  * @param sequenceID - the ID to use
76  * @param avgPower - the average power, in linear format
77  * @param maxPower - the max power, in linear format
78  *
79  * @return vector<uint8_t> the record buffer
80  */
81 std::vector<uint8_t> makeRawRecord(uint8_t sequenceID, uint16_t avgPower,
82                                    uint16_t maxPower)
83 {
84     std::vector<uint8_t> record;
85 
86     record.push_back(sequenceID);
87     record.push_back(avgPower & 0xFF);
88     record.push_back(avgPower >> 8);
89     record.push_back(maxPower & 0xFF);
90     record.push_back(maxPower >> 8);
91 
92     return record;
93 }
94 
95 /**
96  * Test record queue management
97  */
98 TEST(ManagerTest, TestRecordAdds)
99 {
100     // Hold 5 max records.  IDs roll over at 8.
101     RecordManager mgr{5, 8};
102 
103     EXPECT_EQ(0, mgr.getNumRecords());
104 
105     mgr.add(makeRawRecord(0, 0, 0));
106     EXPECT_EQ(1, mgr.getNumRecords());
107 
108     mgr.add(makeRawRecord(1, 0, 0));
109     EXPECT_EQ(2, mgr.getNumRecords());
110 
111     mgr.add(makeRawRecord(2, 0, 0));
112     EXPECT_EQ(3, mgr.getNumRecords());
113 
114     mgr.add(makeRawRecord(3, 0, 0));
115     EXPECT_EQ(4, mgr.getNumRecords());
116 
117     mgr.add(makeRawRecord(4, 0, 0));
118     EXPECT_EQ(5, mgr.getNumRecords());
119 
120     // start pruning
121     mgr.add(makeRawRecord(5, 0, 0));
122     EXPECT_EQ(5, mgr.getNumRecords());
123 
124     mgr.add(makeRawRecord(6, 0, 0));
125     EXPECT_EQ(5, mgr.getNumRecords());
126 
127     mgr.add(makeRawRecord(7, 0, 0));
128     EXPECT_EQ(5, mgr.getNumRecords());
129 
130     mgr.add(makeRawRecord(8, 0, 0));
131     EXPECT_EQ(5, mgr.getNumRecords());
132 
133     // rollover
134     mgr.add(makeRawRecord(0, 0, 0));
135     EXPECT_EQ(5, mgr.getNumRecords());
136 
137     mgr.add(makeRawRecord(1, 0, 0));
138     EXPECT_EQ(5, mgr.getNumRecords());
139 
140     // nonsequential ID, clear previous
141     mgr.add(makeRawRecord(4, 0, 10));
142     EXPECT_EQ(1, mgr.getNumRecords());
143 
144     // back to normal
145     mgr.add(makeRawRecord(5, 1, 11));
146     EXPECT_EQ(2, mgr.getNumRecords());
147 
148     // One more good record
149     mgr.add(makeRawRecord(6, 2, 12));
150     EXPECT_EQ(3, mgr.getNumRecords());
151 
152     // Add a garbage length record. No size change
153     mgr.add(std::vector<uint8_t>(6, 0));
154     EXPECT_EQ(3, mgr.getNumRecords());
155 
156     // Test the DBus Records
157     auto avgRecords = mgr.getAverageRecords();
158     EXPECT_EQ(3, avgRecords.size());
159 
160     auto maxRecords = mgr.getMaximumRecords();
161     EXPECT_EQ(3, maxRecords.size());
162 
163     auto avg = 2;
164     for (const auto& r : avgRecords)
165     {
166         EXPECT_EQ(avg, std::get<1>(r));
167         avg--;
168     }
169 
170     auto max = 12;
171     for (const auto& r : maxRecords)
172     {
173         EXPECT_EQ(max, std::get<1>(r));
174         max--;
175     }
176 
177     // Add a zero length record. Records cleared.
178     mgr.add(std::vector<uint8_t>{});
179     EXPECT_EQ(0, mgr.getNumRecords());
180 }
181