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