1 
2 #include "libpldm/entity.h"
3 #include "libpldm/platform.h"
4 
5 #include "platform-mc/numeric_sensor.hpp"
6 #include "platform-mc/terminus.hpp"
7 
8 #include <gtest/gtest.h>
9 
TEST(NumericSensor,conversionFormula)10 TEST(NumericSensor, conversionFormula)
11 {
12     std::vector<uint8_t> pdr1{
13         0x1,
14         0x0,
15         0x0,
16         0x0,                     // record handle
17         0x1,                     // PDRHeaderVersion
18         PLDM_NUMERIC_SENSOR_PDR, // PDRType
19         0x0,
20         0x0,                     // recordChangeNumber
21         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
22             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
23             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
24         0,                             // dataLength
25         0,
26         0,                             // PLDMTerminusHandle
27         0x1,
28         0x0,                           // sensorID=1
29         PLDM_ENTITY_POWER_SUPPLY,
30         0,                             // entityType=Power Supply(120)
31         1,
32         0,                             // entityInstanceNumber
33         0x1,
34         0x0,                           // containerID=1
35         PLDM_NO_INIT,                  // sensorInit
36         false,                         // sensorAuxiliaryNamesPDR
37         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
38         1,                             // unitModifier = 1
39         0,                             // rateUnit
40         0,                             // baseOEMUnitHandle
41         0,                             // auxUnit
42         0,                             // auxUnitModifier
43         0,                             // auxRateUnit
44         0,                             // rel
45         0,                             // auxOEMUnitHandle
46         true,                          // isLinear
47         PLDM_RANGE_FIELD_FORMAT_SINT8, // sensorDataSize
48         0,
49         0,
50         0xc0,
51         0x3f, // resolution=1.5
52         0,
53         0,
54         0x80,
55         0x3f, // offset=1.0
56         0,
57         0,    // accuracy
58         0,    // plusTolerance
59         0,    // minusTolerance
60         2,    // hysteresis
61         0,    // supportedThresholds
62         0,    // thresholdAndHysteresisVolatility
63         0,
64         0,
65         0x80,
66         0x3f, // stateTransistionInterval=1.0
67         0,
68         0,
69         0x80,
70         0x3f,                          // updateInverval=1.0
71         255,                           // maxReadable
72         0,                             // minReadable
73         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
74         0,                             // rangeFieldsupport
75         0,                             // nominalValue
76         0,                             // normalMax
77         0,                             // normalMin
78         0,                             // warningHigh
79         0,                             // warningLow
80         0,                             // criticalHigh
81         0,                             // criticalLow
82         0,                             // fatalHigh
83         0                              // fatalLow
84     };
85 
86     auto numericSensorPdr = std::make_shared<pldm_numeric_sensor_value_pdr>();
87     std::printf("pdr size=%ld\n", pdr1.size());
88     auto rc = decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(),
89                                              numericSensorPdr.get());
90     EXPECT_EQ(rc, PLDM_SUCCESS);
91 
92     std::string sensorName{"test1"};
93     std::string inventoryPath{
94         "/xyz/openbmc_project/inventroy/Item/Board/PLDM_device_1"};
95     pldm::platform_mc::NumericSensor sensor(0x01, true, numericSensorPdr,
96                                             sensorName, inventoryPath);
97     double reading = 40.0;
98     double convertedValue = 0;
99     convertedValue = sensor.conversionFormula(reading);
100     convertedValue = sensor.unitModifier(convertedValue);
101 
102     // (40*1.5 + 1.0 ) * 10^1 = 610
103     EXPECT_EQ(610, convertedValue);
104 }
105 
TEST(NumericSensor,checkThreshold)106 TEST(NumericSensor, checkThreshold)
107 {
108     std::vector<uint8_t> pdr1{
109         0x1,
110         0x0,
111         0x0,
112         0x0,                     // record handle
113         0x1,                     // PDRHeaderVersion
114         PLDM_NUMERIC_SENSOR_PDR, // PDRType
115         0x0,
116         0x0,                     // recordChangeNumber
117         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
118             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
119             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
120         0,                             // dataLength
121         0,
122         0,                             // PLDMTerminusHandle
123         0x1,
124         0x0,                           // sensorID=1
125         PLDM_ENTITY_POWER_SUPPLY,
126         0,                             // entityType=Power Supply(120)
127         1,
128         0,                             // entityInstanceNumber
129         0x1,
130         0x0,                           // containerID=1
131         PLDM_NO_INIT,                  // sensorInit
132         false,                         // sensorAuxiliaryNamesPDR
133         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
134         1,                             // unitModifier = 1
135         0,                             // rateUnit
136         0,                             // baseOEMUnitHandle
137         0,                             // auxUnit
138         0,                             // auxUnitModifier
139         0,                             // auxRateUnit
140         0,                             // rel
141         0,                             // auxOEMUnitHandle
142         true,                          // isLinear
143         PLDM_RANGE_FIELD_FORMAT_SINT8, // sensorDataSize
144         0,
145         0,
146         0xc0,
147         0x3f, // resolution=1.5
148         0,
149         0,
150         0x80,
151         0x3f, // offset=1.0
152         0,
153         0,    // accuracy
154         0,    // plusTolerance
155         0,    // minusTolerance
156         2,    // hysteresis
157         0,    // supportedThresholds
158         0,    // thresholdAndHysteresisVolatility
159         0,
160         0,
161         0x80,
162         0x3f, // stateTransistionInterval=1.0
163         0,
164         0,
165         0x80,
166         0x3f,                          // updateInverval=1.0
167         255,                           // maxReadable
168         0,                             // minReadable
169         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
170         0,                             // rangeFieldsupport
171         0,                             // nominalValue
172         0,                             // normalMax
173         0,                             // normalMin
174         0,                             // warningHigh
175         0,                             // warningLow
176         0,                             // criticalHigh
177         0,                             // criticalLow
178         0,                             // fatalHigh
179         0                              // fatalLow
180     };
181 
182     auto numericSensorPdr = std::make_shared<pldm_numeric_sensor_value_pdr>();
183     auto rc = decode_numeric_sensor_pdr_data(pdr1.data(), pdr1.size(),
184                                              numericSensorPdr.get());
185     EXPECT_EQ(rc, PLDM_SUCCESS);
186     std::string sensorName{"test1"};
187     std::string inventoryPath{
188         "/xyz/openbmc_project/inventroy/Item/Board/PLDM_device_1"};
189     pldm::platform_mc::NumericSensor sensor(0x01, true, numericSensorPdr,
190                                             sensorName, inventoryPath);
191 
192     bool highAlarm = false;
193     bool lowAlarm = false;
194     double highThreshold = 40;
195     double lowThreshold = 30;
196     double hysteresis = 2;
197 
198     // reading     35->40->45->38->35->30->25->32->35
199     // highAlarm    F->T ->T ->T ->F ->F ->F -> F-> F
200     // lowAlarm     F->F ->F ->F ->F ->T ->T -> T ->F
201     double reading = 35;
202     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
203                                       hysteresis);
204     EXPECT_EQ(false, highAlarm);
205     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
206                                      hysteresis);
207     EXPECT_EQ(false, lowAlarm);
208 
209     reading = 40;
210     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
211                                       hysteresis);
212     EXPECT_EQ(true, highAlarm);
213     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
214                                      hysteresis);
215     EXPECT_EQ(false, lowAlarm);
216 
217     reading = 45;
218     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
219                                       hysteresis);
220     EXPECT_EQ(true, highAlarm);
221     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
222                                      hysteresis);
223     EXPECT_EQ(false, lowAlarm);
224 
225     reading = 38;
226     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
227                                       hysteresis);
228     EXPECT_EQ(true, highAlarm);
229     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
230                                      hysteresis);
231     EXPECT_EQ(false, lowAlarm);
232 
233     reading = 35;
234     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
235                                       hysteresis);
236     EXPECT_EQ(false, highAlarm);
237     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
238                                      hysteresis);
239     EXPECT_EQ(false, lowAlarm);
240 
241     reading = 30;
242     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
243                                       hysteresis);
244     EXPECT_EQ(false, highAlarm);
245     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
246                                      hysteresis);
247     EXPECT_EQ(true, lowAlarm);
248 
249     reading = 25;
250     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
251                                       hysteresis);
252     EXPECT_EQ(false, highAlarm);
253     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
254                                      hysteresis);
255     EXPECT_EQ(true, lowAlarm);
256 
257     reading = 32;
258     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
259                                       hysteresis);
260     EXPECT_EQ(false, highAlarm);
261     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
262                                      hysteresis);
263     EXPECT_EQ(true, lowAlarm);
264 
265     reading = 35;
266     highAlarm = sensor.checkThreshold(highAlarm, true, reading, highThreshold,
267                                       hysteresis);
268     EXPECT_EQ(false, highAlarm);
269     lowAlarm = sensor.checkThreshold(lowAlarm, false, reading, lowThreshold,
270                                      hysteresis);
271     EXPECT_EQ(false, lowAlarm);
272 }
273