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 <gtest/gtest.h>
17 #include <iostream>
18 #include "names_values.hpp"
19 #include "../record_manager.hpp"
20 
21 using namespace witherspoon::power::history;
22 
23 /**
24  * Test the linearToInteger function with different
25  * combinations of positive and negative mantissas and
26  * exponents.
27  *
28  * Value = mantissa * 2**exponent
29  */
30 TEST(LinearFormatTest, TestConversions)
31 {
32     //Mantissa > 0, exponent = 0
33     EXPECT_EQ(0, RecordManager::linearToInteger(0));
34     EXPECT_EQ(1, RecordManager::linearToInteger(1));
35     EXPECT_EQ(38, RecordManager::linearToInteger(0x26));
36     EXPECT_EQ(1023, RecordManager::linearToInteger(0x3FF));
37 
38     //Mantissa < 0, exponent = 0
39     EXPECT_EQ(-1, RecordManager::linearToInteger(0x7FF));
40     EXPECT_EQ(-20, RecordManager::linearToInteger(0x7EC));
41     EXPECT_EQ(-769, RecordManager::linearToInteger(0x4FF));
42     EXPECT_EQ(-989, RecordManager::linearToInteger(0x423));
43     EXPECT_EQ(-1024, RecordManager::linearToInteger(0x400));
44 
45     //Mantissa >= 0, exponent > 0
46     //M = 1, E = 2
47     EXPECT_EQ(4, RecordManager::linearToInteger(0x1001));
48 
49     //M = 1000, E = 10
50     EXPECT_EQ(1024000, RecordManager::linearToInteger(0x53E8));
51 
52     //M = 10, E = 15
53     EXPECT_EQ(327680, RecordManager::linearToInteger(0x780A));
54 
55     //Mantissa >= 0, exponent < 0
56     //M = 0, E = -1
57     EXPECT_EQ(0, RecordManager::linearToInteger(0xF800));
58 
59     //M = 100, E = -2
60     EXPECT_EQ(25, RecordManager::linearToInteger(0xF064));
61 
62     //Mantissa < 0, exponent < 0
63     //M = -100, E = -1
64     EXPECT_EQ(-50, RecordManager::linearToInteger(0xFF9C));
65 
66     //M = -1024, E = -7
67     EXPECT_EQ(-8, RecordManager::linearToInteger(0xCC00));
68 }
69 
70 /**
71  * @brief Helper function to create a record buffer
72  *
73  * @param sequenceID - the ID to use
74  * @param avgPower - the average power, in linear format
75  * @param maxPower - the max power, in linear format
76  *
77  * @return vector<uint8_t> the record buffer
78  */
79 std::vector<uint8_t> makeRawRecord(
80         uint8_t sequenceID,
81         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 /**
97  * Test record queue management
98  */
99 TEST(ManagerTest, TestRecordAdds)
100 {
101     //Hold 5 max records.  IDs roll over at 8.
102     RecordManager mgr{5, 8};
103 
104     EXPECT_EQ(0, mgr.getNumRecords());
105 
106     mgr.add(makeRawRecord(0, 0, 0));
107     EXPECT_EQ(1, mgr.getNumRecords());
108 
109     mgr.add(makeRawRecord(1, 0, 0));
110     EXPECT_EQ(2, mgr.getNumRecords());
111 
112     mgr.add(makeRawRecord(2, 0, 0));
113     EXPECT_EQ(3, mgr.getNumRecords());
114 
115     mgr.add(makeRawRecord(3, 0, 0));
116     EXPECT_EQ(4, mgr.getNumRecords());
117 
118     mgr.add(makeRawRecord(4, 0, 0));
119     EXPECT_EQ(5, mgr.getNumRecords());
120 
121     //start pruning
122     mgr.add(makeRawRecord(5, 0, 0));
123     EXPECT_EQ(5, mgr.getNumRecords());
124 
125     mgr.add(makeRawRecord(6, 0, 0));
126     EXPECT_EQ(5, mgr.getNumRecords());
127 
128     mgr.add(makeRawRecord(7, 0, 0));
129     EXPECT_EQ(5, mgr.getNumRecords());
130 
131     mgr.add(makeRawRecord(8, 0, 0));
132     EXPECT_EQ(5, mgr.getNumRecords());
133 
134     //rollover
135     mgr.add(makeRawRecord(0, 0, 0));
136     EXPECT_EQ(5, mgr.getNumRecords());
137 
138     mgr.add(makeRawRecord(1, 0, 0));
139     EXPECT_EQ(5, mgr.getNumRecords());
140 
141     //nonsequential ID, clear previous
142     mgr.add(makeRawRecord(4, 0, 10));
143     EXPECT_EQ(1, mgr.getNumRecords());
144 
145     //back to normal
146     mgr.add(makeRawRecord(5, 1, 11));
147     EXPECT_EQ(2, mgr.getNumRecords());
148 
149     //One more good record
150     mgr.add(makeRawRecord(6, 2, 12));
151     EXPECT_EQ(3, mgr.getNumRecords());
152 
153     //Add a garbage length record. No size change
154     mgr.add(std::vector<uint8_t>(6, 0));
155     EXPECT_EQ(3, mgr.getNumRecords());
156 
157     //Test the DBus Records
158     auto avgRecords = mgr.getAverageRecords();
159     EXPECT_EQ(3, avgRecords.size());
160 
161     auto maxRecords = mgr.getMaximumRecords();
162     EXPECT_EQ(3, maxRecords.size());
163 
164     auto avg = 2;
165     for (const auto& r : avgRecords)
166     {
167         EXPECT_EQ(avg, std::get<1>(r));
168         avg--;
169     }
170 
171     auto max = 12;
172     for (const auto& r : maxRecords)
173     {
174         EXPECT_EQ(max, std::get<1>(r));
175         max--;
176     }
177 
178     //Add a zero length record. Records cleared.
179     mgr.add(std::vector<uint8_t>{});
180     EXPECT_EQ(0, mgr.getNumRecords());
181 }
182 
183