blob: 6b89b2e3f640be06a83f4af5146482eeef038e87 [file] [log] [blame]
Sampa Misraa2fa0702019-05-31 01:28:55 -05001#include "libpldmresponder/effecters.hpp"
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05302#include "libpldmresponder/pdr.hpp"
3#include "libpldmresponder/platform.hpp"
4
5#include <iostream>
6
Sampa Misraa2fa0702019-05-31 01:28:55 -05007#include <gmock/gmock-matchers.h>
8#include <gmock/gmock.h>
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05309#include <gtest/gtest.h>
10
11using namespace pldm::responder;
Sampa Misraa2fa0702019-05-31 01:28:55 -050012using namespace pldm::responder::pdr;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053013
14TEST(getPDR, testGoodPath)
15{
16 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
17 requestPayload{};
18 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
19 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
20
21 uint8_t* start = request->payload;
22 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
23 uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
24 *reqCount = 100;
25 using namespace pdr;
26 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
27 ASSERT_EQ(pdrRepo.empty(), false);
28 auto response = getPDR(request, requestPayloadLength);
29 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
30
31 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
32 start = responsePtr->payload;
33 start += sizeof(uint8_t);
34 uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
35 ASSERT_EQ(*nextRecordHandle, 2);
36 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
37 uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
38 ASSERT_EQ(*recordCount != 0, true);
39 start += sizeof(uint16_t);
40 // Check a bit of the PDR common header
41 pldm_state_effecter_pdr* pdr =
42 reinterpret_cast<pldm_state_effecter_pdr*>(start);
43 ASSERT_EQ(pdr->hdr.record_handle, 1);
44 ASSERT_EQ(pdr->hdr.version, 1);
45}
46
47TEST(getPDR, testShortRead)
48{
49 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
50 requestPayload{};
51 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
52 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
53
54 uint8_t* start = request->payload;
55 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
56 uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
57 // Read 1 byte of PDR
58 *reqCount = 1;
59 using namespace pdr;
60 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
61 ASSERT_EQ(pdrRepo.empty(), false);
62 auto response = getPDR(request, requestPayloadLength);
63 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
64
65 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
66 start = responsePtr->payload;
67 start +=
68 sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
69 uint16_t* recordCount = reinterpret_cast<uint16_t*>(start);
70 ASSERT_EQ(*recordCount, 1);
71}
72
73TEST(getPDR, testBadRecordHandle)
74{
75 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
76 requestPayload{};
77 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
78 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
79
80 uint8_t* start = request->payload;
81 uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
82 *recordHandle = 100000;
83 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
84 uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
85 *reqCount = 1;
86 using namespace pdr;
87 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
88 ASSERT_EQ(pdrRepo.empty(), false);
89 auto response = getPDR(request, requestPayloadLength);
90 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
91
92 ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
93}
94
95TEST(getPDR, testNoNextRecord)
96{
97 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
98 requestPayload{};
99 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
100 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
101
102 uint8_t* start = request->payload;
103 uint32_t* recordHandle = reinterpret_cast<uint32_t*>(start);
104 *recordHandle = 3;
105 using namespace pdr;
106 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
107 ASSERT_EQ(pdrRepo.empty(), false);
108 auto response = getPDR(request, requestPayloadLength);
109 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
110
111 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
112 start = responsePtr->payload;
113 start += sizeof(uint8_t);
114 uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
115 ASSERT_EQ(*nextRecordHandle, 0);
116}
117
118TEST(getPDR, testFindPDR)
119{
120 std::array<uint8_t, sizeof(pldm_msg_hdr) + PLDM_GET_PDR_REQ_BYTES>
121 requestPayload{};
122 auto request = reinterpret_cast<pldm_msg*>(requestPayload.data());
123 size_t requestPayloadLength = requestPayload.size() - sizeof(pldm_msg_hdr);
124
125 uint8_t* start = request->payload;
126 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
127 uint16_t* reqCount = reinterpret_cast<uint16_t*>(start);
128 *reqCount = 100;
129 using namespace pdr;
130 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
131 ASSERT_EQ(pdrRepo.empty(), false);
132 auto response = getPDR(request, requestPayloadLength);
133
134 // Let's try to find a PDR of type stateEffecter (= 11) and entity type =
135 // 100
136 bool found = false;
137 uint32_t handle = 0; // start asking for PDRs from recordHandle 0
138 uint32_t* recordHandle = nullptr;
139 while (!found)
140 {
141 start = request->payload;
142 recordHandle = reinterpret_cast<uint32_t*>(start);
143 *recordHandle = handle;
144 auto response = getPDR(request, requestPayloadLength);
145 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
146
147 ASSERT_EQ(responsePtr->payload[0], PLDM_SUCCESS);
148 start = responsePtr->payload;
149 start += sizeof(uint8_t);
150 uint32_t* nextRecordHandle = reinterpret_cast<uint32_t*>(start);
151 handle = *nextRecordHandle; // point to the next pdr in case current is
152 // not what we want
153 start += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) +
154 sizeof(uint16_t);
155 pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(start);
156 uint32_t intType = hdr->type;
157 std::cerr << "PDR next record handle " << handle << std::endl;
158 std::cerr << "PDR type " << intType << std::endl;
159 if (hdr->type == PLDM_STATE_EFFECTER_PDR)
160 {
161 pldm_state_effecter_pdr* pdr =
162 reinterpret_cast<pldm_state_effecter_pdr*>(start);
163 std::cerr << "PDR entity type " << pdr->entity_type << std::endl;
164 if (pdr->entity_type == 100)
165 {
166 found = true;
167 // Rest of the PDR can be accessed as need be
168 break;
169 }
170 }
171 if (!*nextRecordHandle) // no more records
172 {
173 break;
174 }
175 }
176 ASSERT_EQ(found, true);
177}
Sampa Misraa2fa0702019-05-31 01:28:55 -0500178
179namespace pldm
180{
181
182namespace responder
183{
184
185class MockdBusHandler
186{
187 public:
188 MOCK_CONST_METHOD4(setDbusProperty,
189 int(const std::string&, const std::string&,
190 const std::string&,
191 const std::variant<std::string>&));
192};
193} // namespace responder
194} // namespace pldm
195
196using ::testing::_;
197using ::testing::Return;
198
199TEST(setStateEffecterStatesHandler, testGoodRequest)
200{
201 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
202 pdr::Entry e = pdrRepo.at(1);
203 pldm_state_effecter_pdr* pdr =
204 reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
205 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
206
207 std::vector<set_effecter_state_field> stateField;
208 stateField.push_back({PLDM_REQUEST_SET, 1});
209 stateField.push_back({PLDM_REQUEST_SET, 1});
210
211 auto bootProgressInf = "xyz.openbmc_project.State.OperatingSystem.Status";
212 auto bootProgressProp = "OperatingSystemState";
213 std::string objPath = "/foo/bar";
214 std::variant<std::string> value{"xyz.openbmc_project.State.OperatingSystem."
215 "Status.OSStatus.Standby"};
216
217 MockdBusHandler handlerObj;
218 EXPECT_CALL(handlerObj, setDbusProperty(objPath, bootProgressProp,
219 bootProgressInf, value))
220 .Times(2);
221 auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
222 stateField);
223 ASSERT_EQ(rc, 0);
224}
225
226TEST(setStateEffecterStatesHandler, testBadRequest)
227{
228 Repo& pdrRepo = get("./pdr_jsons/state_effecter/good");
229 pdr::Entry e = pdrRepo.at(1);
230 pldm_state_effecter_pdr* pdr =
231 reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
232 EXPECT_EQ(pdr->hdr.type, PLDM_STATE_EFFECTER_PDR);
233
234 std::vector<set_effecter_state_field> stateField;
235 stateField.push_back({PLDM_REQUEST_SET, 3});
236 stateField.push_back({PLDM_REQUEST_SET, 4});
237
238 MockdBusHandler handlerObj;
239 auto rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
240 stateField);
241 ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
242
243 rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x9,
244 stateField);
245 ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_EFFECTER_ID);
246
247 stateField.push_back({PLDM_REQUEST_SET, 4});
248 rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x1,
249 stateField);
250 ASSERT_EQ(rc, PLDM_ERROR_INVALID_DATA);
251
252 std::vector<set_effecter_state_field> newStateField;
253 newStateField.push_back({PLDM_REQUEST_SET, 1});
254
255 rc = setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x2,
256 newStateField);
257 ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
258}