1 #include "common/instance_id.hpp"
2 #include "common/types.hpp"
3 #include "mock_sensor_manager.hpp"
4 #include "platform-mc/terminus_manager.hpp"
5 #include "test/test_instance_id.hpp"
6 
7 #include <sdeventplus/event.hpp>
8 
9 #include <gtest/gtest.h>
10 
11 using namespace ::testing;
12 
13 class SensorManagerTest : public testing::Test
14 {
15   protected:
16     SensorManagerTest() :
17         bus(pldm::utils::DBusHandler::getBus()),
18         event(sdeventplus::Event::get_default()), instanceIdDb(),
19         reqHandler(pldmTransport, event, instanceIdDb, false),
20         terminusManager(event, reqHandler, instanceIdDb, termini, nullptr,
21                         pldm::BmcMctpEid),
22         sensorManager(event, terminusManager, termini)
23     {}
24 
25     void runEventLoopForSeconds(uint64_t sec)
26     {
27         uint64_t t0 = 0;
28         uint64_t t1 = 0;
29         uint64_t usec = sec * 1000000;
30         uint64_t elapsed = 0;
31         sd_event_now(event.get(), CLOCK_MONOTONIC, &t0);
32         do
33         {
34             if (!sd_event_run(event.get(), usec - elapsed))
35             {
36                 break;
37             }
38             sd_event_now(event.get(), CLOCK_MONOTONIC, &t1);
39             elapsed = t1 - t0;
40         } while (elapsed < usec);
41     }
42 
43     PldmTransport* pldmTransport = nullptr;
44     sdbusplus::bus_t& bus;
45     sdeventplus::Event event;
46     TestInstanceIdDb instanceIdDb;
47     pldm::requester::Handler<pldm::requester::Request> reqHandler;
48     pldm::platform_mc::TerminusManager terminusManager;
49     pldm::platform_mc::MockSensorManager sensorManager;
50     std::map<pldm_tid_t, std::shared_ptr<pldm::platform_mc::Terminus>> termini;
51 
52     std::vector<uint8_t> pdr1{
53         0x1,
54         0x0,
55         0x0,
56         0x0,                     // record handle
57         0x1,                     // PDRHeaderVersion
58         PLDM_NUMERIC_SENSOR_PDR, // PDRType
59         0x0,
60         0x0,                     // recordChangeNumber
61         PLDM_PDR_NUMERIC_SENSOR_PDR_FIXED_LENGTH +
62             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_SENSOR_DATA_SIZE_MIN_LENGTH +
63             PLDM_PDR_NUMERIC_SENSOR_PDR_VARIED_RANGE_FIELD_MIN_LENGTH,
64         0,                             // dataLength
65         0,
66         0,                             // PLDMTerminusHandle
67         0x1,
68         0x0,                           // sensorID=1
69         PLDM_ENTITY_POWER_SUPPLY,
70         0,                             // entityType=Power Supply(120)
71         1,
72         0,                             // entityInstanceNumber
73         0x1,
74         0x0,                           // containerID=1
75         PLDM_NO_INIT,                  // sensorInit
76         false,                         // sensorAuxiliaryNamesPDR
77         PLDM_SENSOR_UNIT_DEGRESS_C,    // baseUint(2)=degrees C
78         1,                             // unitModifier = 1
79         0,                             // rateUnit
80         0,                             // baseOEMUnitHandle
81         0,                             // auxUnit
82         0,                             // auxUnitModifier
83         0,                             // auxRateUnit
84         0,                             // rel
85         0,                             // auxOEMUnitHandle
86         true,                          // isLinear
87         PLDM_RANGE_FIELD_FORMAT_SINT8, // sensorDataSize
88         0,
89         0,
90         0xc0,
91         0x3f, // resolution=1.5
92         0,
93         0,
94         0x80,
95         0x3f, // offset=1.0
96         0,
97         0,    // accuracy
98         0,    // plusTolerance
99         0,    // minusTolerance
100         2,    // hysteresis
101         0,    // supportedThresholds
102         0,    // thresholdAndHysteresisVolatility
103         0,
104         0,
105         0x80,
106         0x3f, // stateTransistionInterval=1.0
107         0,
108         0,
109         0x80,
110         0x3f,                          // updateInverval=1.0
111         255,                           // maxReadable
112         0,                             // minReadable
113         PLDM_RANGE_FIELD_FORMAT_UINT8, // rangeFieldFormat
114         0,                             // rangeFieldsupport
115         0,                             // nominalValue
116         0,                             // normalMax
117         0,                             // normalMin
118         0,                             // warningHigh
119         0,                             // warningLow
120         0,                             // criticalHigh
121         0,                             // criticalLow
122         0,                             // fatalHigh
123         0                              // fatalLow
124     };
125 
126     std::vector<uint8_t> pdr2{
127         0x1, 0x0, 0x0,
128         0x0,                             // record handle
129         0x1,                             // PDRHeaderVersion
130         PLDM_ENTITY_AUXILIARY_NAMES_PDR, // PDRType
131         0x1,
132         0x0,                             // recordChangeNumber
133         0x11,
134         0,                               // dataLength
135         /* Entity Auxiliary Names PDR Data*/
136         3,
137         0x80, // entityType system software
138         0x1,
139         0x0,  // Entity instance number =1
140         0,
141         0,    // Overal system
142         0,    // shared Name Count one name only
143         01,   // nameStringCount
144         0x65, 0x6e, 0x00,
145         0x00, // Language Tag "en"
146         0x53, 0x00, 0x30, 0x00,
147         0x00  // Entity Name "S0"
148     };
149 };
150 
151 TEST_F(SensorManagerTest, sensorPollingTest)
152 {
153     uint64_t seconds = 10;
154 
155     pldm_tid_t tid = 1;
156     termini[tid] = std::make_shared<pldm::platform_mc::Terminus>(tid, 0);
157     termini[tid]->pdrs.push_back(pdr1);
158     termini[tid]->pdrs.push_back(pdr2);
159     termini[tid]->parseTerminusPDRs();
160 
161     uint64_t t0, t1;
162     ASSERT_TRUE(sd_event_now(event.get(), CLOCK_MONOTONIC, &t0) >= 0);
163     ON_CALL(sensorManager, doSensorPolling(tid))
164         .WillByDefault([this, &t0, &t1](unsigned char) {
165             ASSERT_TRUE(sd_event_now(event.get(), CLOCK_MONOTONIC, &t1) >= 0);
166             EXPECT_GE(t1 - t0, SENSOR_POLLING_TIME * 1000);
167             t0 = t1;
168         });
169     EXPECT_CALL(sensorManager, doSensorPolling(tid))
170         .Times(AtLeast(2))
171         .WillRepeatedly(Return());
172 
173     sensorManager.startPolling(tid);
174 
175     runEventLoopForSeconds(seconds);
176 
177     sensorManager.stopPolling(tid);
178 }
179