xref: /openbmc/dbus-sensors/src/tests/test_NvidiaGpuSensorTest.cpp (revision 87a0745bbf15a7f8a23bc5183e3640bd3a92db08)
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     std::array<uint8_t, sizeof(gpu::GetCurrentPowerDrawRequest)> buf{};
652 
653     int result = gpu::encodeGetCurrentPowerDrawRequest(instanceId, sensorId,
654                                                        averagingInterval, buf);
655 
656     EXPECT_EQ(result, 0);
657 
658     gpu::GetCurrentPowerDrawRequest request{};
659     std::memcpy(&request, buf.data(), sizeof(request));
660 
661     EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
662               htobe16(gpu::nvidiaPciVendorId));
663     EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
664                   ocp::accelerator_management::instanceIdBitMask,
665               instanceId & ocp::accelerator_management::instanceIdBitMask);
666     EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
667                   ocp::accelerator_management::requestBitMask,
668               0);
669     EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
670               static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
671 
672     // Verify request data
673     EXPECT_EQ(request.hdr.command,
674               static_cast<uint8_t>(
675                   gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW));
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::GetCurrentPowerDrawResponse)> buf{};
687 
688     gpu::GetCurrentPowerDrawResponse 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 =
717         gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
718 
719     EXPECT_EQ(result, 0);
720     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
721     EXPECT_EQ(reasonCode, 0);
722     EXPECT_EQ(power, 250U);
723 }
724 
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseError)725 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseError)
726 {
727     std::array<uint8_t,
728                sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
729         buf{};
730 
731     // Populate error response data
732     ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
733     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
734     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
735         ocp::accelerator_management::MessageType::RESPONSE);
736     headerInfo.instance_id = 6;
737     headerInfo.msg_type =
738         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
739 
740     gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
741 
742     errorResponse.command = static_cast<uint8_t>(
743         gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
744     errorResponse.completion_code = static_cast<uint8_t>(
745         ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
746     errorResponse.reason_code = htole16(0x9ABC);
747 
748     std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
749 
750     // Test decoding
751     ocp::accelerator_management::CompletionCode cc{};
752     uint16_t reasonCode{};
753     uint32_t power{};
754 
755     int result =
756         gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
757 
758     EXPECT_EQ(result, 0);
759     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
760     EXPECT_EQ(reasonCode, 0x9ABC);
761 }
762 
TEST_F(GpuMctpVdmTests,DecodeGetCurrentPowerDrawResponseInvalidSize)763 TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseInvalidSize)
764 {
765     // Create a mock response with invalid data_size
766     std::array<uint8_t, sizeof(gpu::GetCurrentPowerDrawResponse)> buf{};
767 
768     gpu::GetCurrentPowerDrawResponse response{};
769     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
770     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
771         ocp::accelerator_management::MessageType::RESPONSE);
772     headerInfo.instance_id = 6;
773     headerInfo.msg_type =
774         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
775 
776     gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
777 
778     response.hdr.command = static_cast<uint8_t>(
779         gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW);
780     response.hdr.completion_code = static_cast<uint8_t>(
781         ocp::accelerator_management::CompletionCode::SUCCESS);
782     response.hdr.reserved = 0;
783     response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
784     response.power = htole32(250);
785 
786     std::memcpy(buf.data(), &response, sizeof(response));
787 
788     // Test decoding
789     ocp::accelerator_management::CompletionCode cc{};
790     uint16_t reasonCode{};
791     uint32_t power{};
792 
793     int result =
794         gpu::decodeGetCurrentPowerDrawResponse(buf, cc, reasonCode, power);
795 
796     EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
797 }
798 
799 // Tests for GpuMctpVdm::encodeGetCurrentEnergyCounterRequest function
TEST_F(GpuMctpVdmTests,EncodeGetCurrentEnergyCounterRequestSuccess)800 TEST_F(GpuMctpVdmTests, EncodeGetCurrentEnergyCounterRequestSuccess)
801 {
802     const uint8_t instanceId = 7;
803     const uint8_t sensorId = 3;
804     std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterRequest)> buf{};
805 
806     int result =
807         gpu::encodeGetCurrentEnergyCounterRequest(instanceId, sensorId, buf);
808 
809     EXPECT_EQ(result, 0);
810 
811     gpu::GetCurrentEnergyCounterRequest request{};
812     std::memcpy(&request, buf.data(), sizeof(request));
813 
814     EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
815               htobe16(gpu::nvidiaPciVendorId));
816     EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
817                   ocp::accelerator_management::instanceIdBitMask,
818               instanceId & ocp::accelerator_management::instanceIdBitMask);
819     EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
820                   ocp::accelerator_management::requestBitMask,
821               0);
822     EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
823               static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
824 
825     // Verify request data
826     EXPECT_EQ(
827         request.hdr.command,
828         static_cast<uint8_t>(
829             gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER));
830     EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
831     EXPECT_EQ(request.sensor_id, sensorId);
832 }
833 
834 // Tests for GpuMctpVdm::decodeGetCurrentEnergyCounterResponse function
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseSuccess)835 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseSuccess)
836 {
837     // Create a mock successful response
838     std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
839 
840     gpu::GetCurrentEnergyCounterResponse response{};
841     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
842     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
843         ocp::accelerator_management::MessageType::RESPONSE);
844     headerInfo.instance_id = 7;
845     headerInfo.msg_type =
846         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
847 
848     gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
849 
850     // Populate response data
851     response.hdr.command = static_cast<uint8_t>(
852         gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
853     response.hdr.completion_code = static_cast<uint8_t>(
854         ocp::accelerator_management::CompletionCode::SUCCESS);
855     response.hdr.reserved = 0;
856     response.hdr.data_size = htole16(sizeof(uint64_t));
857 
858     // Set an energy value of 1000 Wh (1000 * 3600 = 3600000 Joules)
859     response.energy = htole64(3600000);
860 
861     std::memcpy(buf.data(), &response, sizeof(response));
862 
863     // Test decoding
864     ocp::accelerator_management::CompletionCode cc{};
865     uint16_t reasonCode{};
866     uint64_t energy{};
867 
868     int result =
869         gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
870 
871     EXPECT_EQ(result, 0);
872     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
873     EXPECT_EQ(reasonCode, 0);
874     EXPECT_EQ(energy, 3600000U);
875 }
876 
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseError)877 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseError)
878 {
879     std::array<uint8_t,
880                sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
881         buf{};
882 
883     // Populate error response data
884     ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
885     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
886     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
887         ocp::accelerator_management::MessageType::RESPONSE);
888     headerInfo.instance_id = 7;
889     headerInfo.msg_type =
890         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
891 
892     gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
893 
894     errorResponse.command = static_cast<uint8_t>(
895         gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
896     errorResponse.completion_code = static_cast<uint8_t>(
897         ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
898     errorResponse.reason_code = htole16(0xDEF0);
899 
900     std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
901 
902     // Test decoding
903     ocp::accelerator_management::CompletionCode cc{};
904     uint16_t reasonCode{};
905     uint64_t energy{};
906 
907     int result =
908         gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
909 
910     EXPECT_EQ(result, 0);
911     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
912     EXPECT_EQ(reasonCode, 0xDEF0);
913 }
914 
TEST_F(GpuMctpVdmTests,DecodeGetCurrentEnergyCounterResponseInvalidSize)915 TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseInvalidSize)
916 {
917     // Create a mock response with invalid data_size
918     std::array<uint8_t, sizeof(gpu::GetCurrentEnergyCounterResponse)> buf{};
919 
920     gpu::GetCurrentEnergyCounterResponse response{};
921     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
922     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
923         ocp::accelerator_management::MessageType::RESPONSE);
924     headerInfo.instance_id = 7;
925     headerInfo.msg_type =
926         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
927 
928     gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
929 
930     response.hdr.command = static_cast<uint8_t>(
931         gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER);
932     response.hdr.completion_code = static_cast<uint8_t>(
933         ocp::accelerator_management::CompletionCode::SUCCESS);
934     response.hdr.reserved = 0;
935     response.hdr.data_size = htole16(4); // Invalid - should be sizeof(uint64_t)
936     response.energy = htole64(3600000);
937 
938     std::memcpy(buf.data(), &response, sizeof(response));
939 
940     // Test decoding
941     ocp::accelerator_management::CompletionCode cc{};
942     uint16_t reasonCode{};
943     uint64_t energy{};
944 
945     int result =
946         gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy);
947 
948     EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
949 }
950 
951 // Tests for GpuMctpVdm::encodeGetVoltageRequest function
TEST_F(GpuMctpVdmTests,EncodeGetVoltageRequestSuccess)952 TEST_F(GpuMctpVdmTests, EncodeGetVoltageRequestSuccess)
953 {
954     const uint8_t instanceId = 8;
955     const uint8_t sensorId = 4;
956     std::array<uint8_t, sizeof(gpu::GetVoltageRequest)> buf{};
957 
958     int result = gpu::encodeGetVoltageRequest(instanceId, sensorId, buf);
959 
960     EXPECT_EQ(result, 0);
961 
962     gpu::GetVoltageRequest request{};
963     std::memcpy(&request, buf.data(), sizeof(request));
964 
965     EXPECT_EQ(request.hdr.msgHdr.hdr.pci_vendor_id,
966               htobe16(gpu::nvidiaPciVendorId));
967     EXPECT_EQ(request.hdr.msgHdr.hdr.instance_id &
968                   ocp::accelerator_management::instanceIdBitMask,
969               instanceId & ocp::accelerator_management::instanceIdBitMask);
970     EXPECT_NE(request.hdr.msgHdr.hdr.instance_id &
971                   ocp::accelerator_management::requestBitMask,
972               0);
973     EXPECT_EQ(request.hdr.msgHdr.hdr.ocp_accelerator_management_msg_type,
974               static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL));
975 
976     // Verify request data
977     EXPECT_EQ(
978         request.hdr.command,
979         static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE));
980     EXPECT_EQ(request.hdr.data_size, sizeof(sensorId));
981     EXPECT_EQ(request.sensor_id, sensorId);
982 }
983 
984 // Tests for GpuMctpVdm::decodeGetVoltageResponse function
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseSuccess)985 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseSuccess)
986 {
987     // Create a mock successful response
988     std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
989 
990     gpu::GetVoltageResponse response{};
991     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
992     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
993         ocp::accelerator_management::MessageType::RESPONSE);
994     headerInfo.instance_id = 8;
995     headerInfo.msg_type =
996         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
997 
998     gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
999 
1000     // Populate response data
1001     response.hdr.command =
1002         static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1003     response.hdr.completion_code = static_cast<uint8_t>(
1004         ocp::accelerator_management::CompletionCode::SUCCESS);
1005     response.hdr.reserved = 0;
1006     response.hdr.data_size = htole16(sizeof(uint32_t));
1007 
1008     // Set a voltage value of 12.5V (12.5 * 1000 = 12500 mV)
1009     response.voltage = htole32(12500);
1010 
1011     std::memcpy(buf.data(), &response, sizeof(response));
1012 
1013     // Test decoding
1014     ocp::accelerator_management::CompletionCode cc{};
1015     uint16_t reasonCode{};
1016     uint32_t voltage{};
1017 
1018     int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1019 
1020     EXPECT_EQ(result, 0);
1021     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS);
1022     EXPECT_EQ(reasonCode, 0);
1023     EXPECT_EQ(voltage, 12500U);
1024 }
1025 
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseError)1026 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseError)
1027 {
1028     std::array<uint8_t,
1029                sizeof(ocp::accelerator_management::CommonNonSuccessResponse)>
1030         buf{};
1031 
1032     // Populate error response data
1033     ocp::accelerator_management::CommonNonSuccessResponse errorResponse{};
1034     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1035     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1036         ocp::accelerator_management::MessageType::RESPONSE);
1037     headerInfo.instance_id = 8;
1038     headerInfo.msg_type =
1039         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1040 
1041     gpu::packHeader(headerInfo, errorResponse.msgHdr.hdr);
1042 
1043     errorResponse.command =
1044         static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1045     errorResponse.completion_code = static_cast<uint8_t>(
1046         ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1047     errorResponse.reason_code = htole16(0x1234);
1048 
1049     std::memcpy(buf.data(), &errorResponse, sizeof(errorResponse));
1050 
1051     // Test decoding
1052     ocp::accelerator_management::CompletionCode cc{};
1053     uint16_t reasonCode{};
1054     uint32_t voltage{};
1055 
1056     int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1057 
1058     EXPECT_EQ(result, 0);
1059     EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY);
1060     EXPECT_EQ(reasonCode, 0x1234);
1061 }
1062 
TEST_F(GpuMctpVdmTests,DecodeGetVoltageResponseInvalidSize)1063 TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseInvalidSize)
1064 {
1065     // Create a mock response with invalid data_size
1066     std::array<uint8_t, sizeof(gpu::GetVoltageResponse)> buf{};
1067 
1068     gpu::GetVoltageResponse response{};
1069     ocp::accelerator_management::BindingPciVidInfo headerInfo{};
1070     headerInfo.ocp_accelerator_management_msg_type = static_cast<uint8_t>(
1071         ocp::accelerator_management::MessageType::RESPONSE);
1072     headerInfo.instance_id = 8;
1073     headerInfo.msg_type =
1074         static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL);
1075 
1076     gpu::packHeader(headerInfo, response.hdr.msgHdr.hdr);
1077 
1078     response.hdr.command =
1079         static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_VOLTAGE);
1080     response.hdr.completion_code = static_cast<uint8_t>(
1081         ocp::accelerator_management::CompletionCode::SUCCESS);
1082     response.hdr.reserved = 0;
1083     response.hdr.data_size = htole16(2); // Invalid - should be sizeof(uint32_t)
1084     response.voltage = htole32(12500);
1085 
1086     std::memcpy(buf.data(), &response, sizeof(response));
1087 
1088     // Test decoding
1089     ocp::accelerator_management::CompletionCode cc{};
1090     uint16_t reasonCode{};
1091     uint32_t voltage{};
1092 
1093     int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage);
1094 
1095     EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size
1096 }
1097 } // namespace gpu_mctp_tests
1098