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