1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3 * AFFILIATES. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "NvidiaGpuMctpVdm.hpp"
8 #include "OcpMctpVdm.hpp"
9
10 #include <endian.h>
11
12 #include <array>
13 #include <cerrno>
14 #include <cstdint>
15 #include <cstring>
16 #include <vector>
17
18 #include <gtest/gtest.h>
19
20 namespace ocp_mctp_tests
21 {
22
23 class OcpMctpVdmTests : public ::testing::Test
24 {
25 protected:
SetUp()26 void SetUp() override
27 {
28 // Initialize common test data here
29 }
30 };
31
32 // Tests for OcpMctpVdm::packHeader function
TEST_F(OcpMctpVdmTests,PackHeaderRequestSuccess)33 TEST_F(OcpMctpVdmTests, PackHeaderRequestSuccess)
34 {
35 const uint16_t pciVendorId = 0x1234;
36 ocp::accelerator_management::BindingPciVidInfo hdr{};
37 ocp::accelerator_management::BindingPciVid msg{};
38
39 hdr.ocp_accelerator_management_msg_type =
40 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
41 hdr.instance_id = 5;
42 hdr.msg_type = 0x7E;
43
44 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
45
46 EXPECT_EQ(result, 0);
47 EXPECT_EQ(msg.pci_vendor_id, htobe16(pciVendorId));
48 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
49 5);
50 EXPECT_NE(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
51 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
52 EXPECT_EQ((msg.ocp_version & 0xF0) >>
53 ocp::accelerator_management::ocpTypeBitOffset,
54 ocp::accelerator_management::ocpType);
55 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
56 }
57
TEST_F(OcpMctpVdmTests,PackHeaderResponseSuccess)58 TEST_F(OcpMctpVdmTests, PackHeaderResponseSuccess)
59 {
60 const uint16_t pciVendorId = 0x1234;
61 ocp::accelerator_management::BindingPciVidInfo hdr{};
62 ocp::accelerator_management::BindingPciVid msg{};
63
64 hdr.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
65 ocp::accelerator_management::MessageType::RESPONSE);
66 hdr.instance_id = 10;
67 hdr.msg_type = 0x7E;
68
69 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
70
71 EXPECT_EQ(result, 0);
72 EXPECT_EQ(msg.pci_vendor_id, htobe16(pciVendorId));
73 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
74 10);
75 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
76 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
77 EXPECT_EQ((msg.ocp_version & 0xF0) >>
78 ocp::accelerator_management::ocpTypeBitOffset,
79 ocp::accelerator_management::ocpType);
80 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
81 }
82
TEST_F(OcpMctpVdmTests,PackHeaderInvalidMessageType)83 TEST_F(OcpMctpVdmTests, PackHeaderInvalidMessageType)
84 {
85 const uint16_t pciVendorId = 0x1234;
86 ocp::accelerator_management::BindingPciVidInfo hdr{};
87 ocp::accelerator_management::BindingPciVid msg{};
88
89 hdr.ocp_accelerator_management_msg_type = 3; // Invalid message type
90 hdr.instance_id = 5;
91 hdr.msg_type = 0x7E;
92
93 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
94
95 EXPECT_EQ(result, EINVAL);
96 }
97
TEST_F(OcpMctpVdmTests,PackHeaderInvalidInstanceId)98 TEST_F(OcpMctpVdmTests, PackHeaderInvalidInstanceId)
99 {
100 const uint16_t pciVendorId = 0x1234;
101 ocp::accelerator_management::BindingPciVidInfo hdr{};
102 ocp::accelerator_management::BindingPciVid msg{};
103
104 hdr.ocp_accelerator_management_msg_type =
105 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
106 hdr.instance_id = 32; // Out of range (0-31 valid)
107 hdr.msg_type = 0x7E;
108
109 int result = ocp::accelerator_management::packHeader(pciVendorId, hdr, msg);
110
111 EXPECT_EQ(result, EINVAL);
112 }
113
114 // Tests for OcpMctpVdm::decodeReasonCodeAndCC function
TEST_F(OcpMctpVdmTests,DecodeReasonCodeAndCCSuccessCase)115 TEST_F(OcpMctpVdmTests, DecodeReasonCodeAndCCSuccessCase)
116 {
117 ocp::accelerator_management::CommonNonSuccessResponse response{};
118 response.command = 0x42;
119 response.completion_code = static_cast<uint8_t>(
120 ocp::accelerator_management::CompletionCode::SUCCESS);
121 response.reason_code = htole16(0x1234);
122
123 ocp::accelerator_management::CompletionCode cc{};
124 uint16_t reasonCode{};
125
126 std::array<uint8_t, sizeof(response)> buf{};
127 std::memcpy(buf.data(), &response, sizeof(response));
128
129 int result =
130 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
131
132 EXPECT_EQ(result, 0);
133 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
134 EXPECT_EQ(reasonCode, 0); // Should be 0 for SUCCESS
135 }
136
TEST_F(OcpMctpVdmTests,DecodeReasonCodeAndCCErrorCase)137 TEST_F(OcpMctpVdmTests, DecodeReasonCodeAndCCErrorCase)
138 {
139 ocp::accelerator_management::CommonNonSuccessResponse response{};
140 response.command = 0x42;
141 response.completion_code = static_cast<uint8_t>(
142 ocp::accelerator_management::CompletionCode::ERROR);
143 response.reason_code = htole16(0x5678);
144
145 ocp::accelerator_management::CompletionCode cc{};
146 uint16_t reasonCode{};
147
148 std::array<uint8_t, sizeof(response)> buf{};
149 std::memcpy(buf.data(), &response, sizeof(response));
150
151 int result =
152 ocp::accelerator_management::decodeReasonCodeAndCC(buf, cc, reasonCode);
153
154 EXPECT_EQ(result, 0);
155 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR);
156 EXPECT_EQ(reasonCode, 0x5678);
157 }
158
159 } // namespace ocp_mctp_tests
160
161 namespace gpu_mctp_tests
162 {
163
164 class GpuMctpVdmTests : public ::testing::Test
165 {
166 protected:
SetUp()167 void SetUp() override
168 {
169 // Initialize common test data here
170 }
171 };
172
173 // Tests for GpuMctpVdm::packHeader function
TEST_F(GpuMctpVdmTests,PackHeaderSuccess)174 TEST_F(GpuMctpVdmTests, PackHeaderSuccess)
175 {
176 ocp::accelerator_management::BindingPciVidInfo hdr{};
177 ocp::accelerator_management::BindingPciVid msg{};
178
179 hdr.ocp_accelerator_management_msg_type =
180 static_cast<uint8_t>(ocp::accelerator_management::MessageType::REQUEST);
181 hdr.instance_id = 5;
182 hdr.msg_type = 0x7E;
183
184 int result = gpu::packHeader(hdr, msg);
185
186 EXPECT_EQ(result, 0);
187 EXPECT_EQ(msg.pci_vendor_id, htobe16(gpu::nvidiaPciVendorId));
188 EXPECT_EQ(msg.instance_id & ocp::accelerator_management::instanceIdBitMask,
189 5);
190 EXPECT_NE(msg.instance_id & ocp::accelerator_management::requestBitMask, 0);
191 EXPECT_EQ(msg.ocp_version & 0x0F, ocp::accelerator_management::ocpVersion);
192 EXPECT_EQ((msg.ocp_version & 0xF0) >>
193 ocp::accelerator_management::ocpTypeBitOffset,
194 ocp::accelerator_management::ocpType);
195 EXPECT_EQ(msg.ocp_accelerator_management_msg_type, 0x7E);
196 }
197
198 // Tests for GpuMctpVdm::encodeQueryDeviceIdentificationRequest function
TEST_F(GpuMctpVdmTests,EncodeQueryDeviceIdentificationRequestSuccess)199 TEST_F(GpuMctpVdmTests, EncodeQueryDeviceIdentificationRequestSuccess)
200 {
201 const uint8_t instanceId = 3;
202 std::vector<uint8_t> buf(256);
203
204 int result = gpu::encodeQueryDeviceIdentificationRequest(instanceId, buf);
205
206 EXPECT_EQ(result, 0);
207
208 gpu::QueryDeviceIdentificationRequest request{};
209 std::memcpy(&request, buf.data(), sizeof(request));
210
211 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
212 htobe16(gpu::nvidiaPciVendorId));
213 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
214 ocp::accelerator_management::instanceIdBitMask,
215 instanceId & ocp::accelerator_management::instanceIdBitMask);
216 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
217 ocp::accelerator_management::requestBitMask,
218 0);
219
220 EXPECT_EQ(request.hdr.command,
221 static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands::
222 QUERY_DEVICE_IDENTIFICATION));
223 EXPECT_EQ(request.hdr.data_size, 0);
224 }
225
226 // Tests for GpuMctpVdm::decodeQueryDeviceIdentificationResponse function
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseSuccess)227 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseSuccess)
228 {
229 // Create a mock successful response
230 std::vector<uint8_t> buf(sizeof(gpu::QueryDeviceIdentificationResponse));
231
232 gpu::QueryDeviceIdentificationResponse response{};
233 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
234 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
235 ocp::accelerator_management::MessageType::RESPONSE);
236 headerInfo.instance_id = 3;
237 headerInfo.msg_type =
238 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
239
240 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
241
242 // Populate response data
243 response.hdr.command = static_cast<uint8_t>(
244 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
245 response.hdr.completion_code = static_cast<uint8_t>(
246 ocp::accelerator_management::CompletionCode::SUCCESS);
247 response.hdr.reserved = 0;
248 response.hdr.data_size =
249 htole16(2); // Size of device_identification + instance_id
250 response.device_identification =
251 static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU);
252 response.instance_id = 7;
253
254 std::memcpy(buf.data(), &response, sizeof(response));
255
256 // Test decoding
257 ocp::accelerator_management::CompletionCode cc{};
258 uint16_t reasonCode{};
259 uint8_t deviceIdentification{};
260 uint8_t deviceInstance{};
261
262 int result = gpu::decodeQueryDeviceIdentificationResponse(
263 buf, cc, reasonCode, deviceIdentification, deviceInstance);
264
265 EXPECT_EQ(result, 0);
266 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
267 EXPECT_EQ(reasonCode, 0);
268 EXPECT_EQ(deviceIdentification,
269 static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU));
270 EXPECT_EQ(deviceInstance, 7);
271 }
272
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseError)273 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseError)
274 {
275 // Create a mock successful response
276 std::vector<uint8_t> buf(
277 sizeof(ocp::accelerator_management::CommonNonSuccessResponse));
278
279 ocp::accelerator_management::CommonNonSuccessResponse response{};
280 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
281 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
282 ocp::accelerator_management::MessageType::RESPONSE);
283 headerInfo.instance_id = 3;
284 headerInfo.msg_type =
285 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
286
287 gpu::packHeader(headerInfo, response.msgHdr.hdr);
288
289 // Populate response data
290 response.command = static_cast<uint8_t>(
291 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
292 response.command = static_cast<uint8_t>(
293 gpu::DeviceCapabilityDiscoveryCommands::QUERY_DEVICE_IDENTIFICATION);
294 response.completion_code = static_cast<uint8_t>(
295 ocp::accelerator_management::CompletionCode::ERROR);
296 response.reason_code = htole16(0x1234);
297
298 std::memcpy(buf.data(), &response, sizeof(response));
299
300 // Test decoding
301 ocp::accelerator_management::CompletionCode cc{};
302 uint16_t reasonCode{};
303 uint8_t deviceIdentification{};
304 uint8_t deviceInstance{};
305
306 int result = gpu::decodeQueryDeviceIdentificationResponse(
307 buf, cc, reasonCode, deviceIdentification, deviceInstance);
308
309 EXPECT_EQ(result, 0);
310 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR);
311 EXPECT_EQ(reasonCode, 0x1234);
312 }
313
TEST_F(GpuMctpVdmTests,DecodeQueryDeviceIdentificationResponseInvalidSize)314 TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseInvalidSize)
315 {
316 // Create a too-small buffer
317 std::vector<uint8_t> buf(
318 sizeof(ocp::accelerator_management::Message) + 2); // Too small
319
320 // Populate Message header only
321 ocp::accelerator_management::Message msg{};
322 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
323 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
324 ocp::accelerator_management::MessageType::RESPONSE);
325 headerInfo.instance_id = 3;
326 headerInfo.msg_type =
327 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
328
329 gpu::packHeader(headerInfo, msg.hdr);
330 std::memcpy(buf.data(), &msg, sizeof(msg));
331
332 // Test decoding with insufficient data
333 ocp::accelerator_management::CompletionCode cc{};
334 uint16_t reasonCode{};
335 uint8_t deviceIdentification{};
336 uint8_t deviceInstance{};
337
338 int result = gpu::decodeQueryDeviceIdentificationResponse(
339 buf, cc, reasonCode, deviceIdentification, deviceInstance);
340
341 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid size
342 }
343
344 // Tests for GpuMctpVdm::encodeGetTemperatureReadingRequest function
TEST_F(GpuMctpVdmTests,EncodeGetTemperatureReadingRequestSuccess)345 TEST_F(GpuMctpVdmTests, EncodeGetTemperatureReadingRequestSuccess)
346 {
347 const uint8_t instanceId = 4;
348 const uint8_t sensorId = 0;
349 std::vector<uint8_t> buf(256);
350
351 int result =
352 gpu::encodeGetTemperatureReadingRequest(instanceId, sensorId, buf);
353
354 EXPECT_EQ(result, 0);
355
356 gpu::GetTemperatureReadingRequest request{};
357 std::memcpy(&request, buf.data(), sizeof(request));
358
359 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
360 htobe16(gpu::nvidiaPciVendorId));
361 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
362 ocp::accelerator_management::instanceIdBitMask,
363 instanceId & ocp::accelerator_management::instanceIdBitMask);
364 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
365 ocp::accelerator_management::requestBitMask,
366 0);
367 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
368 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
369
370 // Verify request data
371 EXPECT_EQ(request.hdr.command,
372 static_cast<uint8_t>(
373 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING));
374 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
375 EXPECT_EQ(request.sensor_id, sensorId);
376 }
377
378 // Tests for GpuMctpVdm::decodeGetTemperatureReadingResponse function
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseSuccess)379 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseSuccess)
380 {
381 // Create a mock successful response
382 std::vector<uint8_t> buf(sizeof(gpu::GetTemperatureReadingResponse));
383
384 gpu::GetTemperatureReadingResponse response{};
385 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
386 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
387 ocp::accelerator_management::MessageType::RESPONSE);
388 headerInfo.instance_id = 4;
389 headerInfo.msg_type =
390 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
391
392 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
393
394 // Populate response data
395 response.hdr.command = static_cast<uint8_t>(
396 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
397 response.hdr.completion_code = static_cast<uint8_t>(
398 ocp::accelerator_management::CompletionCode::SUCCESS);
399 response.hdr.reserved = 0;
400 response.hdr.data_size = htole16(sizeof(int32_t));
401
402 // Set a temperature value of 75.5°C (75.5 * 256 = 19328)
403 response.reading = htole32(19328);
404
405 std::memcpy(buf.data(), &response, sizeof(response));
406
407 // Test decoding
408 ocp::accelerator_management::CompletionCode cc{};
409 uint16_t reasonCode{};
410 double temperatureReading{};
411
412 int result = gpu::decodeGetTemperatureReadingResponse(
413 buf, cc, reasonCode, temperatureReading);
414
415 EXPECT_EQ(result, 0);
416 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
417 EXPECT_EQ(reasonCode, 0);
418 EXPECT_NEAR(temperatureReading, 75.5, 0.01);
419 }
420
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseError)421 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseError)
422 {
423 std::vector<uint8_t> buf(
424 sizeof(ocp::accelerator_management::CommonNonSuccessResponse));
425
426 // Populate error response data
427 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
428 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
429 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
430 ocp::accelerator_management::MessageType::RESPONSE);
431 headerInfo.instance_id = 3;
432 headerInfo.msg_type =
433 static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY);
434
435 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
436
437 errorResponse.command = static_cast<uint8_t>(
438 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
439 errorResponse.completion_code = static_cast<uint8_t>(
440 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
441 errorResponse.reason_code = htole16(0x4321);
442
443 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
444
445 // Test decoding
446 ocp::accelerator_management::CompletionCode cc{};
447 uint16_t reasonCode{};
448 double temperatureReading{};
449
450 int result = gpu::decodeGetTemperatureReadingResponse(
451 buf, cc, reasonCode, temperatureReading);
452
453 EXPECT_EQ(result, 0);
454 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
455 EXPECT_EQ(reasonCode, 0x4321);
456 }
457
TEST_F(GpuMctpVdmTests,DecodeGetTemperatureReadingResponseInvalidSize)458 TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseInvalidSize)
459 {
460 // Create a mock response with invalid data_size
461 std::vector<uint8_t> buf(sizeof(gpu::GetTemperatureReadingResponse));
462
463 gpu::GetTemperatureReadingResponse response{};
464 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
465 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
466 ocp::accelerator_management::MessageType::RESPONSE);
467 headerInfo.instance_id = 4;
468 headerInfo.msg_type =
469 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
470
471 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
472
473 response.hdr.command = static_cast<uint8_t>(
474 gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING);
475 response.hdr.completion_code = static_cast<uint8_t>(
476 ocp::accelerator_management::CompletionCode::SUCCESS);
477 response.hdr.reserved = 0;
478 response.hdr.data_size = htole16(1); // Invalid - should be sizeof(int32_t)
479 response.reading = htole32(19328);
480
481 std::memcpy(buf.data(), &response, sizeof(response));
482
483 // Test decoding
484 ocp::accelerator_management::CompletionCode cc{};
485 uint16_t reasonCode{};
486 double temperatureReading{};
487
488 int result = gpu::decodeGetTemperatureReadingResponse(
489 buf, cc, reasonCode, temperatureReading);
490
491 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
492 }
493
494 // Tests for GpuMctpVdm::encodeReadThermalParametersRequest function
TEST_F(GpuMctpVdmTests,EncodeReadThermalParametersRequestSuccess)495 TEST_F(GpuMctpVdmTests, EncodeReadThermalParametersRequestSuccess)
496 {
497 const uint8_t instanceId = 5;
498 const uint8_t sensorId = 1;
499 std::array<uint8_t, sizeof(gpu::ReadThermalParametersRequest)> buf{};
500
501 int result =
502 gpu::encodeReadThermalParametersRequest(instanceId, sensorId, buf);
503
504 EXPECT_EQ(result, 0);
505
506 gpu::ReadThermalParametersRequest request{};
507 std::memcpy(&request, buf.data(), sizeof(request));
508
509 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
510 htobe16(gpu::nvidiaPciVendorId));
511 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
512 ocp::accelerator_management::instanceIdBitMask,
513 instanceId & ocp::accelerator_management::instanceIdBitMask);
514 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
515 ocp::accelerator_management::requestBitMask,
516 0);
517 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
518 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
519
520 // Verify request data
521 EXPECT_EQ(request.hdr.command,
522 static_cast<uint8_t>(
523 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS));
524 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
525 EXPECT_EQ(request.sensor_id, sensorId);
526 }
527
528 // Tests for GpuMctpVdm::decodeReadThermalParametersResponse function
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseSuccess)529 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseSuccess)
530 {
531 // Create a mock successful response
532 std::array<uint8_t, sizeof(gpu::ReadThermalParametersResponse)> buf{};
533
534 gpu::ReadThermalParametersResponse response{};
535 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
536 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
537 ocp::accelerator_management::MessageType::RESPONSE);
538 headerInfo.instance_id = 5;
539 headerInfo.msg_type =
540 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
541
542 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
543
544 // Populate response data
545 response.hdr.command = static_cast<uint8_t>(
546 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
547 response.hdr.completion_code = static_cast<uint8_t>(
548 ocp::accelerator_management::CompletionCode::SUCCESS);
549 response.hdr.reserved = 0;
550 response.hdr.data_size = htole16(sizeof(int32_t));
551
552 // Set a threshold value of 85°C (85 * 256 = 21760)
553 response.threshold = htole32(21760);
554
555 std::memcpy(buf.data(), &response, sizeof(response));
556
557 // Test decoding
558 ocp::accelerator_management::CompletionCode cc{};
559 uint16_t reasonCode{};
560 int32_t threshold{};
561
562 int result = gpu::decodeReadThermalParametersResponse(
563 buf, cc, reasonCode, threshold);
564
565 EXPECT_EQ(result, 0);
566 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
567 EXPECT_EQ(reasonCode, 0);
568 EXPECT_EQ(threshold, 21760);
569 }
570
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseError)571 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseError)
572 {
573 std::array<uint8_t,
574 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
575 buf{};
576
577 // Populate error response data
578 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
579 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
580 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
581 ocp::accelerator_management::MessageType::RESPONSE);
582 headerInfo.instance_id = 5;
583 headerInfo.msg_type =
584 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
585
586 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
587
588 errorResponse.command = static_cast<uint8_t>(
589 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
590 errorResponse.completion_code = static_cast<uint8_t>(
591 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
592 errorResponse.reason_code = htole16(0x5678);
593
594 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
595
596 // Test decoding
597 ocp::accelerator_management::CompletionCode cc{};
598 uint16_t reasonCode{};
599 int32_t threshold{};
600
601 int result = gpu::decodeReadThermalParametersResponse(
602 buf, cc, reasonCode, threshold);
603
604 EXPECT_EQ(result, 0);
605 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
606 EXPECT_EQ(reasonCode, 0x5678);
607 }
608
TEST_F(GpuMctpVdmTests,DecodeReadThermalParametersResponseInvalidSize)609 TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseInvalidSize)
610 {
611 // Create a mock response with invalid data_size
612 std::array<uint8_t, sizeof(gpu::ReadThermalParametersResponse)> buf{};
613
614 gpu::ReadThermalParametersResponse response{};
615 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
616 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
617 ocp::accelerator_management::MessageType::RESPONSE);
618 headerInfo.instance_id = 5;
619 headerInfo.msg_type =
620 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
621
622 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
623
624 response.hdr.command = static_cast<uint8_t>(
625 gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS);
626 response.hdr.completion_code = static_cast<uint8_t>(
627 ocp::accelerator_management::CompletionCode::SUCCESS);
628 response.hdr.reserved = 0;
629 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(int32_t)
630 response.threshold = htole32(21760);
631
632 std::memcpy(buf.data(), &response, sizeof(response));
633
634 // Test decoding
635 ocp::accelerator_management::CompletionCode cc{};
636 uint16_t reasonCode{};
637 int32_t threshold{};
638
639 int result = gpu::decodeReadThermalParametersResponse(
640 buf, cc, reasonCode, threshold);
641
642 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
643 }
644
645 // Tests for GpuMctpVdm::encodeGetCurrentPowerDrawRequest function
TEST_F(GpuMctpVdmTests,EncodeGetCurrentPowerDrawRequestSuccess)646 TEST_F(GpuMctpVdmTests, EncodeGetCurrentPowerDrawRequestSuccess)
647 {
648 const uint8_t instanceId = 6;
649 const uint8_t sensorId = 2;
650 const uint8_t averagingInterval = 10;
651 gpu::PlatformEnvironmentalCommands commandCode =
652 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW;
653 std::array<uint8_t, sizeof(gpu::GetPowerDrawRequest)> buf{};
654
655 int result = gpu::encodeGetPowerDrawRequest(
656 commandCode, instanceId, sensorId, averagingInterval, buf);
657
658 EXPECT_EQ(result, 0);
659
660 gpu::GetPowerDrawRequest request{};
661 std::memcpy(&request, buf.data(), sizeof(request));
662
663 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
664 htobe16(gpu::nvidiaPciVendorId));
665 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
666 ocp::accelerator_management::instanceIdBitMask,
667 instanceId & ocp::accelerator_management::instanceIdBitMask);
668 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
669 ocp::accelerator_management::requestBitMask,
670 0);
671 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
672 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
673
674 // Verify request data
675 EXPECT_EQ(request.hdr.command, static_cast<uint8_t>(commandCode));
676 EXPECT_EQ(request.hdr.data_size,
677 sizeof(sensorId) + sizeof(averagingInterval));
678 EXPECT_EQ(request.sensorId, sensorId);
679 EXPECT_EQ(request.averagingInterval, averagingInterval);
680 }
681
682 // Tests for GpuMctpVdm::decodeGetCurrentPowerDrawResponse function
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseSuccess)683 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseSuccess)
684 {
685 // Create a mock successful response
686 std::array<uint8_t, sizeof(gpu::GetPowerDrawResponse)> buf{};
687
688 gpu::GetPowerDrawResponse response{};
689 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
690 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
691 ocp::accelerator_management::MessageType::RESPONSE);
692 headerInfo.instance_id = 6;
693 headerInfo.msg_type =
694 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
695
696 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
697
698 // Populate response data
699 response.hdr.command = static_cast<uint8_t>(
700 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
701 response.hdr.completion_code = static_cast<uint8_t>(
702 ocp::accelerator_management::CompletionCode::SUCCESS);
703 response.hdr.reserved = 0;
704 response.hdr.data_size = htole16(sizeof(uint32_t));
705
706 // Set a power value of 250W
707 response.power = htole32(250);
708
709 std::memcpy(buf.data(), &response, sizeof(response));
710
711 // Test decoding
712 ocp::accelerator_management::CompletionCode cc{};
713 uint16_t reasonCode{};
714 uint32_t power{};
715
716 int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power);
717
718 EXPECT_EQ(result, 0);
719 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
720 EXPECT_EQ(reasonCode, 0);
721 EXPECT_EQ(power, 250U);
722 }
723
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseError)724 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseError)
725 {
726 std::array<uint8_t,
727 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
728 buf{};
729
730 // Populate error response data
731 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
732 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
733 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
734 ocp::accelerator_management::MessageType::RESPONSE);
735 headerInfo.instance_id = 6;
736 headerInfo.msg_type =
737 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
738
739 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
740
741 errorResponse.command = static_cast<uint8_t>(
742 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
743 errorResponse.completion_code = static_cast<uint8_t>(
744 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
745 errorResponse.reason_code = htole16(0x9ABC);
746
747 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
748
749 // Test decoding
750 ocp::accelerator_management::CompletionCode cc{};
751 uint16_t reasonCode{};
752 uint32_t power{};
753
754 int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power);
755
756 EXPECT_EQ(result, 0);
757 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
758 EXPECT_EQ(reasonCode, 0x9ABC);
759 }
760
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseInvalidSize)761 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseInvalidSize)
762 {
763 // Create a mock response with invalid data_size
764 std::array<uint8_t, sizeof(gpu::GetPowerDrawResponse)> buf{};
765
766 gpu::GetPowerDrawResponse response{};
767 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
768 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
769 ocp::accelerator_management::MessageType::RESPONSE);
770 headerInfo.instance_id = 6;
771 headerInfo.msg_type =
772 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
773
774 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
775
776 response.hdr.command = static_cast<uint8_t>(
777 gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
778 response.hdr.completion_code = static_cast<uint8_t>(
779 ocp::accelerator_management::CompletionCode::SUCCESS);
780 response.hdr.reserved = 0;
781 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
782 response.power = htole32(250);
783
784 std::memcpy(buf.data(), &response, sizeof(response));
785
786 // Test decoding
787 ocp::accelerator_management::CompletionCode cc{};
788 uint16_t reasonCode{};
789 uint32_t power{};
790
791 int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power);
792
793 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
794 }
795
796 // Tests for GpuMctpVdm::encodeGetCurrentEnergyCounterRequest function
TEST_F(GpuMctpVdmTests,EncodeGetCurrentEnergyCounterRequestSuccess)797 TEST_F(GpuMctpVdmTests, EncodeGetCurrentEnergyCounterRequestSuccess)
798 {
799 const uint8_t instanceId = 7;
800 const uint8_t sensorId = 3;
801 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterRequest)> buf{};
802
803 int result =
804 gpu::encodeGetCurrentEnergyCounterRequest(instanceId, sensorId, buf);
805
806 EXPECT_EQ(result, 0);
807
808 gpu::GetCurrentEnergyCounterRequest request{};
809 std::memcpy(&request, buf.data(), sizeof(request));
810
811 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
812 htobe16(gpu::nvidiaPciVendorId));
813 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
814 ocp::accelerator_management::instanceIdBitMask,
815 instanceId & ocp::accelerator_management::instanceIdBitMask);
816 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
817 ocp::accelerator_management::requestBitMask,
818 0);
819 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
820 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
821
822 // Verify request data
823 EXPECT_EQ(
824 request.hdr.command,
825 static_cast<uint8_t>(
826 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER));
827 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
828 EXPECT_EQ(request.sensor_id, sensorId);
829 }
830
831 // Tests for GpuMctpVdm::decodeGetCurrentEnergyCounterResponse function
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseSuccess)832 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseSuccess)
833 {
834 // Create a mock successful response
835 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
836
837 gpu::GetCurrentEnergyCounterResponse response{};
838 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
839 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
840 ocp::accelerator_management::MessageType::RESPONSE);
841 headerInfo.instance_id = 7;
842 headerInfo.msg_type =
843 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
844
845 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
846
847 // Populate response data
848 response.hdr.command = static_cast<uint8_t>(
849 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
850 response.hdr.completion_code = static_cast<uint8_t>(
851 ocp::accelerator_management::CompletionCode::SUCCESS);
852 response.hdr.reserved = 0;
853 response.hdr.data_size = htole16(sizeof(uint64_t));
854
855 // Set an energy value of 1000 Wh (1000 * 3600 = 3600000 Joules)
856 response.energy = htole64(3600000);
857
858 std::memcpy(buf.data(), &response, sizeof(response));
859
860 // Test decoding
861 ocp::accelerator_management::CompletionCode cc{};
862 uint16_t reasonCode{};
863 uint64_t energy{};
864
865 int result =
866 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
867
868 EXPECT_EQ(result, 0);
869 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
870 EXPECT_EQ(reasonCode, 0);
871 EXPECT_EQ(energy, 3600000U);
872 }
873
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseError)874 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseError)
875 {
876 std::array<uint8_t,
877 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
878 buf{};
879
880 // Populate error response data
881 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
882 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
883 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
884 ocp::accelerator_management::MessageType::RESPONSE);
885 headerInfo.instance_id = 7;
886 headerInfo.msg_type =
887 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
888
889 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
890
891 errorResponse.command = static_cast<uint8_t>(
892 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
893 errorResponse.completion_code = static_cast<uint8_t>(
894 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
895 errorResponse.reason_code = htole16(0xDEF0);
896
897 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
898
899 // Test decoding
900 ocp::accelerator_management::CompletionCode cc{};
901 uint16_t reasonCode{};
902 uint64_t energy{};
903
904 int result =
905 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
906
907 EXPECT_EQ(result, 0);
908 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
909 EXPECT_EQ(reasonCode, 0xDEF0);
910 }
911
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseInvalidSize)912 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseInvalidSize)
913 {
914 // Create a mock response with invalid data_size
915 std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
916
917 gpu::GetCurrentEnergyCounterResponse response{};
918 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
919 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
920 ocp::accelerator_management::MessageType::RESPONSE);
921 headerInfo.instance_id = 7;
922 headerInfo.msg_type =
923 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
924
925 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
926
927 response.hdr.command = static_cast<uint8_t>(
928 gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
929 response.hdr.completion_code = static_cast<uint8_t>(
930 ocp::accelerator_management::CompletionCode::SUCCESS);
931 response.hdr.reserved = 0;
932 response.hdr.data_size = htole16(4); // Invalid - should be sizeof(uint64_t)
933 response.energy = htole64(3600000);
934
935 std::memcpy(buf.data(), &response, sizeof(response));
936
937 // Test decoding
938 ocp::accelerator_management::CompletionCode cc{};
939 uint16_t reasonCode{};
940 uint64_t energy{};
941
942 int result =
943 gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
944
945 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
946 }
947
948 // Tests for GpuMctpVdm::encodeGetVoltageRequest function
TEST_F(GpuMctpVdmTests,EncodeGetVoltageRequestSuccess)949 TEST_F(GpuMctpVdmTests, EncodeGetVoltageRequestSuccess)
950 {
951 const uint8_t instanceId = 8;
952 const uint8_t sensorId = 4;
953 std::array<uint8_t, sizeof(gpu::GetVoltageRequest)> buf{};
954
955 int result = gpu::encodeGetVoltageRequest(instanceId, sensorId, buf);
956
957 EXPECT_EQ(result, 0);
958
959 gpu::GetVoltageRequest request{};
960 std::memcpy(&request, buf.data(), sizeof(request));
961
962 EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
963 htobe16(gpu::nvidiaPciVendorId));
964 EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
965 ocp::accelerator_management::instanceIdBitMask,
966 instanceId & ocp::accelerator_management::instanceIdBitMask);
967 EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
968 ocp::accelerator_management::requestBitMask,
969 0);
970 EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
971 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
972
973 // Verify request data
974 EXPECT_EQ(
975 request.hdr.command,
976 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE));
977 EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
978 EXPECT_EQ(request.sensor_id, sensorId);
979 }
980
981 // Tests for GpuMctpVdm::decodeGetVoltageResponse function
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseSuccess)982 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseSuccess)
983 {
984 // Create a mock successful response
985 std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
986
987 gpu::GetVoltageResponse response{};
988 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
989 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
990 ocp::accelerator_management::MessageType::RESPONSE);
991 headerInfo.instance_id = 8;
992 headerInfo.msg_type =
993 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
994
995 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
996
997 // Populate response data
998 response.hdr.command =
999 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1000 response.hdr.completion_code = static_cast<uint8_t>(
1001 ocp::accelerator_management::CompletionCode::SUCCESS);
1002 response.hdr.reserved = 0;
1003 response.hdr.data_size = htole16(sizeof(uint32_t));
1004
1005 // Set a voltage value of 12.5V (12.5 * 1000 = 12500 mV)
1006 response.voltage = htole32(12500);
1007
1008 std::memcpy(buf.data(), &response, sizeof(response));
1009
1010 // Test decoding
1011 ocp::accelerator_management::CompletionCode cc{};
1012 uint16_t reasonCode{};
1013 uint32_t voltage{};
1014
1015 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1016
1017 EXPECT_EQ(result, 0);
1018 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
1019 EXPECT_EQ(reasonCode, 0);
1020 EXPECT_EQ(voltage, 12500U);
1021 }
1022
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseError)1023 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseError)
1024 {
1025 std::array<uint8_t,
1026 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
1027 buf{};
1028
1029 // Populate error response data
1030 ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
1031 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1032 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1033 ocp::accelerator_management::MessageType::RESPONSE);
1034 headerInfo.instance_id = 8;
1035 headerInfo.msg_type =
1036 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1037
1038 gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
1039
1040 errorResponse.command =
1041 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1042 errorResponse.completion_code = static_cast<uint8_t>(
1043 ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1044 errorResponse.reason_code = htole16(0x1234);
1045
1046 std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
1047
1048 // Test decoding
1049 ocp::accelerator_management::CompletionCode cc{};
1050 uint16_t reasonCode{};
1051 uint32_t voltage{};
1052
1053 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1054
1055 EXPECT_EQ(result, 0);
1056 EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1057 EXPECT_EQ(reasonCode, 0x1234);
1058 }
1059
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseInvalidSize)1060 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseInvalidSize)
1061 {
1062 // Create a mock response with invalid data_size
1063 std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
1064
1065 gpu::GetVoltageResponse response{};
1066 ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1067 headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1068 ocp::accelerator_management::MessageType::RESPONSE);
1069 headerInfo.instance_id = 8;
1070 headerInfo.msg_type =
1071 static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1072
1073 gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
1074
1075 response.hdr.command =
1076 static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1077 response.hdr.completion_code = static_cast<uint8_t>(
1078 ocp::accelerator_management::CompletionCode::SUCCESS);
1079 response.hdr.reserved = 0;
1080 response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
1081 response.voltage = htole32(12500);
1082
1083 std::memcpy(buf.data(), &response, sizeof(response));
1084
1085 // Test decoding
1086 ocp::accelerator_management::CompletionCode cc{};
1087 uint16_t reasonCode{};
1088 uint32_t voltage{};
1089
1090 int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1091
1092 EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
1093 }
1094 } // namespace gpu_mctp_tests
1095