xref: /openbmc/dbus-sensors/src/tests/test_NvidiaGpuSensorTest.cpp (revision 6b7123225fc4a5180faf89190e9f64a7e248e697)
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