| /* |
| * SPDX-FileCopyrightText: Copyright OpenBMC Authors |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include "MessagePackUnpackUtils.hpp" |
| #include "NvidiaGpuMctpVdm.hpp" |
| #include "OcpMctpVdm.hpp" |
| |
| #include <endian.h> |
| |
| #include <array> |
| #include <bit> |
| #include <cerrno> |
| #include <cstddef> |
| #include <cstdint> |
| #include <cstring> |
| #include <span> |
| #include <string> |
| #include <string_view> |
| #include <utility> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| namespace ocp_mctp_tests |
| { |
| |
| class OcpMctpVdmTests : public ::testing::Test |
| { |
| protected: |
| void SetUp() override |
| { |
| // Initialize common test data here |
| } |
| }; |
| |
| // Tests for OcpMctpVdm::packHeader function (PackBuffer-based) |
| TEST_F(OcpMctpVdmTests, PackHeaderRequestSuccess) |
| { |
| const uint16_t pciVendorId = 0x1234; |
| std::array<uint8_t, 16> buf{}; |
| PackBuffer pbuf(buf); |
| |
| int result = ocp::accelerator_management::packHeader( |
| pbuf, pciVendorId, ocp::accelerator_management::MessageType::REQUEST, 5, |
| 0x7E); |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| // Verify with unpackHeader |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t instanceId = 0; |
| uint8_t msgTypeField = 0; |
| int rc = ocp::accelerator_management::unpackHeader( |
| ubuf, pciVendorId, msgType, instanceId, msgTypeField); |
| EXPECT_EQ(rc, 0); |
| EXPECT_EQ(instanceId, 5); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(msgTypeField, 0x7E); |
| } |
| |
| TEST_F(OcpMctpVdmTests, PackHeaderResponseSuccess) |
| { |
| const uint16_t pciVendorId = 0x1234; |
| std::array<uint8_t, 16> buf{}; |
| PackBuffer pbuf(buf); |
| |
| int result = ocp::accelerator_management::packHeader( |
| pbuf, pciVendorId, ocp::accelerator_management::MessageType::RESPONSE, |
| 10, 0x7E); |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| // Verify with unpackHeader |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t instanceId = 0; |
| uint8_t msgTypeField = 0; |
| int rc = ocp::accelerator_management::unpackHeader( |
| ubuf, pciVendorId, msgType, instanceId, msgTypeField); |
| EXPECT_EQ(rc, 0); |
| EXPECT_EQ(instanceId, 10); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::RESPONSE); |
| EXPECT_EQ(msgTypeField, 0x7E); |
| } |
| |
| TEST_F(OcpMctpVdmTests, PackHeaderInvalidInstanceId) |
| { |
| const uint16_t pciVendorId = 0x1234; |
| std::array<uint8_t, 16> buf{}; |
| PackBuffer pbuf(buf); |
| |
| int result = ocp::accelerator_management::packHeader( |
| pbuf, pciVendorId, ocp::accelerator_management::MessageType::REQUEST, |
| 32, 0x7E); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for OcpMctpVdm::unpackReasonCodeAndCC function |
| TEST_F(OcpMctpVdmTests, UnpackReasonCodeAndCCSuccessCase) |
| { |
| std::array<uint8_t, 16> buf{}; |
| PackBuffer pbuf(buf); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(static_cast<uint16_t>(0x1234)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = ocp::accelerator_management::unpackReasonCodeAndCC( |
| ubuf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); // Should be 0 for SUCCESS |
| } |
| |
| TEST_F(OcpMctpVdmTests, UnpackReasonCodeAndCCErrorCase) |
| { |
| std::array<uint8_t, 16> buf{}; |
| PackBuffer pbuf(buf); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); |
| pbuf.pack(static_cast<uint16_t>(0x5678)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = ocp::accelerator_management::unpackReasonCodeAndCC( |
| ubuf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| // Helper: pack a BindingPciVid header into a PackBuffer for response messages |
| void packResponseHeader(PackBuffer& buffer, uint8_t msgType) |
| { |
| // pci_vendor_id (2 bytes, big-endian) |
| buffer.pack(static_cast<uint16_t>(htobe16(0x10de))); |
| // instance_id: response bit clear, instance=0 |
| buffer.pack(static_cast<uint8_t>(0x00)); |
| // ocp_version: type=8 (upper nibble), version=9 (lower nibble) |
| buffer.pack(static_cast<uint8_t>(0x89)); |
| // ocp_accelerator_management_msg_type |
| buffer.pack(msgType); |
| } |
| |
| // Tests for ocp::accelerator_management::decodeEvent |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventSuccess) |
| { |
| // Event struct: BindingPciVid(5) + version(1) + eventId(1) + |
| // eventClass(1) + eventState(2) + size(1) = 11 bytes |
| std::vector<uint8_t> buf(11); |
| PackBuffer packer(buf); |
| |
| // Pack BindingPciVid header |
| packResponseHeader(packer, 0x03); |
| |
| // version: ack not required (bit 4 = 0), version = 1 |
| packer.pack(static_cast<uint8_t>(0x01)); |
| // eventId |
| packer.pack(static_cast<uint8_t>(0x42)); |
| // eventClass |
| packer.pack(static_cast<uint8_t>(0x03)); |
| // eventState (little-endian) |
| packer.pack(static_cast<uint16_t>(0xBEEF)); |
| // size |
| packer.pack(static_cast<uint8_t>(0)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(messageType, 0x03); |
| EXPECT_FALSE(ackRequired); |
| EXPECT_EQ(version, 1); |
| EXPECT_EQ(eventId, 0x42); |
| EXPECT_EQ(eventClass, 0x03); |
| EXPECT_EQ(eventState, 0xBEEF); |
| EXPECT_EQ(size, 0); |
| EXPECT_TRUE(eventData.empty()); |
| } |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventWithEventData) |
| { |
| // 11 bytes header + 4 bytes event data |
| std::vector<uint8_t> buf(15); |
| PackBuffer packer(buf); |
| |
| packResponseHeader(packer, 0x03); |
| |
| packer.pack(static_cast<uint8_t>(0x02)); // version=2, no ack |
| packer.pack(static_cast<uint8_t>(0x10)); // eventId |
| packer.pack(static_cast<uint8_t>(0x05)); // eventClass |
| packer.pack(static_cast<uint16_t>(0x1234)); // eventState |
| packer.pack(static_cast<uint8_t>(4)); // size = 4 bytes of event data |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| // Fill event data bytes |
| buf[11] = 0xAA; |
| buf[12] = 0xBB; |
| buf[13] = 0xCC; |
| buf[14] = 0xDD; |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(messageType, 0x03); |
| EXPECT_FALSE(ackRequired); |
| EXPECT_EQ(version, 2); |
| EXPECT_EQ(eventId, 0x10); |
| EXPECT_EQ(eventClass, 0x05); |
| EXPECT_EQ(eventState, 0x1234); |
| EXPECT_EQ(size, 4); |
| ASSERT_EQ(eventData.size(), 4); |
| EXPECT_EQ(eventData[0], 0xAA); |
| EXPECT_EQ(eventData[1], 0xBB); |
| EXPECT_EQ(eventData[2], 0xCC); |
| EXPECT_EQ(eventData[3], 0xDD); |
| } |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventAckRequired) |
| { |
| std::vector<uint8_t> buf(11); |
| PackBuffer packer(buf); |
| |
| packResponseHeader(packer, 0x03); |
| |
| // version byte: bit 4 set (ack required) + version=1 => 0x11 |
| packer.pack(static_cast<uint8_t>(0x11)); |
| packer.pack(static_cast<uint8_t>(0x01)); // eventId |
| packer.pack(static_cast<uint8_t>(0x02)); // eventClass |
| packer.pack(static_cast<uint16_t>(0x0001)); // eventState |
| packer.pack(static_cast<uint8_t>(0)); // size |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_TRUE(ackRequired); |
| EXPECT_EQ(version, 1); |
| } |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventAckNotRequired) |
| { |
| std::vector<uint8_t> buf(11); |
| PackBuffer packer(buf); |
| |
| packResponseHeader(packer, 0x03); |
| |
| // version byte: bit 4 clear, version=3 => 0x03 |
| packer.pack(static_cast<uint8_t>(0x03)); |
| packer.pack(static_cast<uint8_t>(0x01)); // eventId |
| packer.pack(static_cast<uint8_t>(0x02)); // eventClass |
| packer.pack(static_cast<uint16_t>(0x0001)); // eventState |
| packer.pack(static_cast<uint8_t>(0)); // size |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_FALSE(ackRequired); |
| EXPECT_EQ(version, 3); |
| } |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventBufferTooSmallForHeader) |
| { |
| // Event header is 11 bytes; provide only 6 |
| std::vector<uint8_t> buf(6, 0); |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(OcpMctpVdmTests, DecodeEventBufferTooSmallForEventData) |
| { |
| // 11 byte header, size says 5 bytes of data, but no trailing data |
| std::vector<uint8_t> buf(11); |
| PackBuffer packer(buf); |
| |
| packResponseHeader(packer, 0x03); |
| |
| packer.pack(static_cast<uint8_t>(0x01)); // version |
| packer.pack(static_cast<uint8_t>(0x01)); // eventId |
| packer.pack(static_cast<uint8_t>(0x02)); // eventClass |
| packer.pack(static_cast<uint16_t>(0x0001)); // eventState |
| packer.pack(static_cast<uint8_t>(5)); // size = 5, but no data follows |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint8_t messageType{}; |
| bool ackRequired{}; |
| uint8_t version{}; |
| uint8_t eventId{}; |
| uint8_t eventClass{}; |
| uint16_t eventState{}; |
| uint8_t size{}; |
| std::span<const uint8_t> eventData; |
| |
| int result = ocp::accelerator_management::decodeEvent( |
| buf, gpu::nvidiaPciVendorId, messageType, ackRequired, version, eventId, |
| eventClass, eventState, size, eventData); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| } // namespace ocp_mctp_tests |
| |
| namespace gpu_mctp_tests |
| { |
| |
| class GpuMctpVdmTests : public ::testing::Test |
| { |
| protected: |
| void SetUp() override |
| { |
| // Initialize common test data here |
| } |
| }; |
| |
| // Tests for GpuMctpVdm::encodeQueryDeviceIdentificationRequest function |
| TEST_F(GpuMctpVdmTests, EncodeQueryDeviceIdentificationRequestSuccess) |
| { |
| const uint8_t instanceId = 3; |
| std::vector<uint8_t> buf(256); |
| |
| int result = gpu::encodeQueryDeviceIdentificationRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ( |
| unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| QUERY_DEVICE_IDENTIFICATION)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeQueryDeviceIdentificationResponse function |
| TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| QUERY_DEVICE_IDENTIFICATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(2)); // data_size |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::DeviceIdentification::DEVICE_GPU)); // device_identification |
| pbuf.pack(static_cast<uint8_t>(7)); // instance_id |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t deviceIdentification{}; |
| uint8_t deviceInstance{}; |
| |
| int result = gpu::decodeQueryDeviceIdentificationResponse( |
| buf, cc, reasonCode, deviceIdentification, deviceInstance); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(deviceIdentification, |
| static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU)); |
| EXPECT_EQ(deviceInstance, 7); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| QUERY_DEVICE_IDENTIFICATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x1234)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t deviceIdentification{}; |
| uint8_t deviceInstance{}; |
| |
| int result = gpu::decodeQueryDeviceIdentificationResponse( |
| buf, cc, reasonCode, deviceIdentification, deviceInstance); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryDeviceIdentificationResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(7); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t deviceIdentification{}; |
| uint8_t deviceInstance{}; |
| |
| int result = gpu::decodeQueryDeviceIdentificationResponse( |
| buf, cc, reasonCode, deviceIdentification, deviceInstance); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetSupportedMessageTypesRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetSupportedMessageTypesRequestSuccess) |
| { |
| const uint8_t instanceId = 3; |
| std::vector<uint8_t> buf(256); |
| |
| int result = gpu::encodeGetSupportedMessageTypesRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ( |
| unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_MESSAGE_TYPES)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetSupportedMessageTypesResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetSupportedMessageTypesResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_MESSAGE_TYPES)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(gpu::supportedListBitfieldSize)); // size |
| pbuf.pack(static_cast<uint8_t>(0x0F)); // byte 0: types 0,1,2,3 supported |
| for (size_t i = 1; i < gpu::supportedListBitfieldSize; ++i) |
| { |
| pbuf.pack(static_cast<uint8_t>(0)); |
| } |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::array<uint8_t, gpu::supportedListBitfieldSize> supportedTypes{}; |
| |
| int result = gpu::decodeGetSupportedMessageTypesResponse( |
| buf, cc, reasonCode, supportedTypes); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(supportedTypes[0], 0x0F); |
| EXPECT_EQ(supportedTypes[1], 0x00); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetSupportedMessageTypesResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_MESSAGE_TYPES)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x1234)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::array<uint8_t, gpu::supportedListBitfieldSize> supportedTypes{}; |
| |
| int result = gpu::decodeGetSupportedMessageTypesResponse( |
| buf, cc, reasonCode, supportedTypes); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetSupportedCommandCodesRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetSupportedCommandCodesRequestSuccess) |
| { |
| const uint8_t instanceId = 5; |
| const uint8_t nvidiaMessageType = |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL); |
| std::vector<uint8_t> buf(256); |
| |
| int result = gpu::encodeGetSupportedCommandCodesRequest( |
| instanceId, nvidiaMessageType, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_COMMAND_CODES)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 1); |
| uint8_t payloadType = 0; |
| ubuf.unpack(payloadType); |
| EXPECT_EQ(payloadType, nvidiaMessageType); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetSupportedCommandCodesResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetSupportedCommandCodesResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_COMMAND_CODES)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(gpu::supportedListBitfieldSize)); // size |
| // command 0x00 and 0x03 supported -> byte 0 = bit0 | bit3 = 0x09 |
| pbuf.pack(static_cast<uint8_t>(0x09)); |
| for (size_t i = 1; i < gpu::supportedListBitfieldSize; ++i) |
| { |
| pbuf.pack(static_cast<uint8_t>(0)); |
| } |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::array<uint8_t, gpu::supportedListBitfieldSize> supportedCommands{}; |
| |
| int result = gpu::decodeGetSupportedCommandCodesResponse( |
| buf, cc, reasonCode, supportedCommands); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(supportedCommands[0], 0x09); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetSupportedCommandCodesResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| pbuf.pack(static_cast<uint8_t>(gpu::DeviceCapabilityDiscoveryCommands:: |
| GET_SUPPORTED_COMMAND_CODES)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::array<uint8_t, gpu::supportedListBitfieldSize> supportedCommands{}; |
| |
| int result = gpu::decodeGetSupportedCommandCodesResponse( |
| buf, cc, reasonCode, supportedCommands); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetTemperatureReadingRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetTemperatureReadingRequestSuccess) |
| { |
| const uint8_t instanceId = 4; |
| const uint8_t sensorId = 0; |
| std::vector<uint8_t> buf(256); |
| |
| int result = |
| gpu::encodeGetTemperatureReadingRequest(instanceId, sensorId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_TEMPERATURE_READING)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(sensorId)); |
| uint8_t unpackedSensorId = 0; |
| ubuf.unpack(unpackedSensorId); |
| EXPECT_EQ(unpackedSensorId, sensorId); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetTemperatureReadingResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 4, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_TEMPERATURE_READING)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(int32_t))); // data_size |
| // Set a temperature value of 75.5C (75.5 * 256 = 19328) |
| pbuf.pack(static_cast<int32_t>(19328)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| double temperatureReading{}; |
| |
| int result = gpu::decodeGetTemperatureReadingResponse( |
| buf, cc, reasonCode, temperatureReading); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_NEAR(temperatureReading, 75.5, 0.01); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_TEMPERATURE_READING)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x4321)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| double temperatureReading{}; |
| |
| int result = gpu::decodeGetTemperatureReadingResponse( |
| buf, cc, reasonCode, temperatureReading); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x4321); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetTemperatureReadingResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 4, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_TEMPERATURE_READING)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(1)); // Invalid data_size |
| pbuf.pack(static_cast<int32_t>(19328)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| double temperatureReading{}; |
| |
| int result = gpu::decodeGetTemperatureReadingResponse( |
| buf, cc, reasonCode, temperatureReading); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeReadThermalParametersRequest function |
| TEST_F(GpuMctpVdmTests, EncodeReadThermalParametersRequestSuccess) |
| { |
| const uint8_t instanceId = 5; |
| const uint8_t sensorId = 1; |
| std::array<uint8_t, gpu::readThermalParametersRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeReadThermalParametersRequest(instanceId, sensorId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::READ_THERMAL_PARAMETERS)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(sensorId)); |
| uint8_t unpackedSensorId = 0; |
| ubuf.unpack(unpackedSensorId); |
| EXPECT_EQ(unpackedSensorId, sensorId); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeReadThermalParametersResponse function |
| TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| READ_THERMAL_PARAMETERS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(int32_t))); // data_size |
| // Set a threshold value of 85C (85 * 256 = 21760) |
| pbuf.pack(static_cast<int32_t>(21760)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| int32_t threshold{}; |
| |
| int result = gpu::decodeReadThermalParametersResponse( |
| buf, cc, reasonCode, threshold); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(threshold, 21760); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| READ_THERMAL_PARAMETERS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| int32_t threshold{}; |
| |
| int result = gpu::decodeReadThermalParametersResponse( |
| buf, cc, reasonCode, threshold); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeReadThermalParametersResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| READ_THERMAL_PARAMETERS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(2)); // Invalid data_size |
| pbuf.pack(static_cast<int32_t>(21760)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| int32_t threshold{}; |
| |
| int result = gpu::decodeReadThermalParametersResponse( |
| buf, cc, reasonCode, threshold); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetCurrentPowerDrawRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentPowerDrawRequestSuccess) |
| { |
| const uint8_t instanceId = 6; |
| const uint8_t sensorId = 2; |
| const uint8_t averagingInterval = 10; |
| gpu::PlatformEnvironmentalCommands commandCode = |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW; |
| std::array<uint8_t, gpu::getPowerDrawRequestSize> buf{}; |
| |
| int result = gpu::encodeGetPowerDrawRequest( |
| commandCode, instanceId, sensorId, averagingInterval, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>(commandCode)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(sensorId) + sizeof(averagingInterval)); |
| uint8_t unpackedSensorId = 0; |
| ubuf.unpack(unpackedSensorId); |
| EXPECT_EQ(unpackedSensorId, sensorId); |
| uint8_t unpackedAvgInterval = 0; |
| ubuf.unpack(unpackedAvgInterval); |
| EXPECT_EQ(unpackedAvgInterval, averagingInterval); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetCurrentPowerDrawResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 6, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(uint32_t))); // data_size |
| pbuf.pack(static_cast<uint32_t>(250)); // power = 250W |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t power{}; |
| |
| int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(power, 250U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 6, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x9ABC)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t power{}; |
| |
| int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x9ABC); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentPowerDrawResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 6, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_POWER_DRAW)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(2)); // Invalid data_size |
| pbuf.pack(static_cast<uint32_t>(250)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t power{}; |
| |
| int result = gpu::decodeGetPowerDrawResponse(buf, cc, reasonCode, power); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetCurrentEnergyCounterRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentEnergyCounterRequestSuccess) |
| { |
| const uint8_t instanceId = 7; |
| const uint8_t sensorId = 3; |
| std::array<uint8_t, gpu::getCurrentEnergyCounterRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeGetCurrentEnergyCounterRequest(instanceId, sensorId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ( |
| command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_ENERGY_COUNTER)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(sensorId)); |
| uint8_t unpackedSensorId = 0; |
| ubuf.unpack(unpackedSensorId); |
| EXPECT_EQ(unpackedSensorId, sensorId); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetCurrentEnergyCounterResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 7, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_CURRENT_ENERGY_COUNTER)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(uint64_t))); // data_size |
| pbuf.pack(static_cast<uint64_t>(3600000)); // energy |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t energy{}; |
| |
| int result = |
| gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(energy, 3600000U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 7, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_CURRENT_ENERGY_COUNTER)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xDEF0)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t energy{}; |
| |
| int result = |
| gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xDEF0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentEnergyCounterResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 7, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_CURRENT_ENERGY_COUNTER)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(4)); // Invalid - should be sizeof(uint64_t) |
| pbuf.pack(static_cast<uint64_t>(3600000)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t energy{}; |
| |
| int result = |
| gpu::decodeGetCurrentEnergyCounterResponse(buf, cc, reasonCode, energy); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetDriverInformationRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetDriverInformationRequestSuccess) |
| { |
| const uint8_t instanceId = 9; |
| std::array<uint8_t, ocp::accelerator_management::commonRequestSize> buf{}; |
| |
| int result = gpu::encodeGetDriverInformationRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetDriverInformationRequestBufferTooSmall) |
| { |
| const uint8_t instanceId = 9; |
| std::array<uint8_t, 1> buf{}; // Too small buffer |
| |
| int result = gpu::encodeGetDriverInformationRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetDriverInformationResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetDriverInformationResponseSuccess) |
| { |
| const std::string expectedVersion = "535.104.05"; |
| const size_t dataSize = |
| sizeof(gpu::DriverState) + expectedVersion.size() + 1; |
| // Size the buffer exactly to match what decoder expects |
| const size_t bufSize = |
| gpu::getDriverInformationResponseMinSize + expectedVersion.size(); |
| std::vector<uint8_t> buf(bufSize); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 9, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(dataSize)); // data_size |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::DriverState::DRIVER_STATE_LOADED)); // driverState |
| // Pack driver version string including null terminator |
| for (size_t i = 0; i <= expectedVersion.size(); i++) |
| { |
| pbuf.pack(static_cast<uint8_t>(expectedVersion.c_str()[i])); |
| } |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::DriverState driverState{}; |
| std::string driverVersion{}; |
| |
| int result = gpu::decodeGetDriverInformationResponse( |
| buf, cc, reasonCode, driverState, driverVersion); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(driverState, gpu::DriverState::DRIVER_STATE_LOADED); |
| EXPECT_EQ(driverVersion, expectedVersion); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetDriverInformationResponseDriverNotLoaded) |
| { |
| const size_t dataSize = |
| sizeof(gpu::DriverState) + 1; // Minimum version size |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 9, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(dataSize)); // data_size |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::DriverState::DRIVER_STATE_NOT_LOADED)); // driverState |
| pbuf.pack(static_cast<uint8_t>('\0')); // null terminator |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::DriverState driverState{}; |
| std::string driverVersion{}; |
| |
| int result = gpu::decodeGetDriverInformationResponse( |
| buf, cc, reasonCode, driverState, driverVersion); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(driverState, gpu::DriverState::DRIVER_STATE_NOT_LOADED); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetDriverInformationResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 9, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xABCD)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::DriverState driverState{}; |
| std::string driverVersion{}; |
| |
| int result = gpu::decodeGetDriverInformationResponse( |
| buf, cc, reasonCode, driverState, driverVersion); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xABCD); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetDriverInformationResponseInvalidSize) |
| { |
| // Create a buffer that's too small - just the header + CC fields |
| std::vector<uint8_t> buf(ocp::accelerator_management::commonResponseSize); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 9, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(2)); // Valid data size but buffer too small |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::DriverState driverState{}; |
| std::string driverVersion{}; |
| |
| int result = gpu::decodeGetDriverInformationResponse( |
| buf, cc, reasonCode, driverState, driverVersion); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid size |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetDriverInformationResponseInvalidDataSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 9, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_DRIVER_INFORMATION)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| // data_size = 1 is invalid (needs at least sizeof(DriverState) + 1 = 2) |
| pbuf.pack(static_cast<uint16_t>(1)); // data_size |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::DriverState driverState{}; |
| std::string driverVersion{}; |
| |
| int result = gpu::decodeGetDriverInformationResponse( |
| buf, cc, reasonCode, driverState, driverVersion); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetVoltageRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetVoltageRequestSuccess) |
| { |
| const uint8_t instanceId = 8; |
| const uint8_t sensorId = 4; |
| std::array<uint8_t, gpu::getVoltageRequestSize> buf{}; |
| |
| int result = gpu::encodeGetVoltageRequest(instanceId, sensorId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VOLTAGE)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(sensorId)); |
| uint8_t unpackedSensorId = 0; |
| ubuf.unpack(unpackedSensorId); |
| EXPECT_EQ(unpackedSensorId, sensorId); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetVoltageResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 8, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VOLTAGE)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(uint32_t))); // data_size |
| pbuf.pack(static_cast<uint32_t>(12500)); // voltage = 12.5V |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t voltage{}; |
| |
| int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(voltage, 12500U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 8, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VOLTAGE)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x1234)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t voltage{}; |
| |
| int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetVoltageResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 8, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VOLTAGE)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(2)); // Invalid data_size |
| pbuf.pack(static_cast<uint32_t>(12500)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t voltage{}; |
| |
| int result = gpu::decodeGetVoltageResponse(buf, cc, reasonCode, voltage); |
| |
| EXPECT_EQ(result, EINVAL); // Should indicate error for invalid data size |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetPowerLimitsRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetPowerLimitsRequestSuccess) |
| { |
| const uint8_t instanceId = 1; |
| const uint32_t powerLimitId = 0; |
| std::array<uint8_t, gpu::getPowerLimitsRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeGetPowerLimitsRequest(instanceId, powerLimitId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_POWER_LIMITS)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(powerLimitId)); |
| uint32_t unpackedPowerLimitId = 0; |
| ubuf.unpack(unpackedPowerLimitId); |
| EXPECT_EQ(unpackedPowerLimitId, powerLimitId); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetPowerLimitsRequestBufferTooSmall) |
| { |
| const uint8_t instanceId = 1; |
| const uint32_t powerLimitId = 0; |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = |
| gpu::encodeGetPowerLimitsRequest(instanceId, powerLimitId, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetPowerLimitsResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetPowerLimitsResponseSuccess) |
| { |
| const uint32_t expectedPersistent = 300; |
| const uint32_t expectedOneshot = 400; |
| const uint32_t expectedEnforced = 250; |
| |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_POWER_LIMITS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(sizeof(uint32_t) * 3)); // data_size |
| pbuf.pack(expectedPersistent); |
| pbuf.pack(expectedOneshot); |
| pbuf.pack(expectedEnforced); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t persistentPowerLimit{}; |
| uint32_t oneshotPowerLimit{}; |
| uint32_t powerLimitEnforced{}; |
| |
| int result = gpu::decodeGetPowerLimitsResponse( |
| buf, cc, reasonCode, persistentPowerLimit, oneshotPowerLimit, |
| powerLimitEnforced); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(persistentPowerLimit, expectedPersistent); |
| EXPECT_EQ(oneshotPowerLimit, expectedOneshot); |
| EXPECT_EQ(powerLimitEnforced, expectedEnforced); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetPowerLimitsResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_POWER_LIMITS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t persistentPowerLimit{}; |
| uint32_t oneshotPowerLimit{}; |
| uint32_t powerLimitEnforced{}; |
| |
| int result = gpu::decodeGetPowerLimitsResponse( |
| buf, cc, reasonCode, persistentPowerLimit, oneshotPowerLimit, |
| powerLimitEnforced); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetPowerLimitsResponseBufferTooSmall) |
| { |
| std::array<uint8_t, 4> buf{}; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t persistentPowerLimit{}; |
| uint32_t oneshotPowerLimit{}; |
| uint32_t powerLimitEnforced{}; |
| |
| int result = gpu::decodeGetPowerLimitsResponse( |
| buf, cc, reasonCode, persistentPowerLimit, oneshotPowerLimit, |
| powerLimitEnforced); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetPowerLimitsResponseInvalidDataSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_POWER_LIMITS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(4)); // data_size (wrong) |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t persistentPowerLimit{}; |
| uint32_t oneshotPowerLimit{}; |
| uint32_t powerLimitEnforced{}; |
| |
| int result = gpu::decodeGetPowerLimitsResponse( |
| buf, cc, reasonCode, persistentPowerLimit, oneshotPowerLimit, |
| powerLimitEnforced); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::encodeSetPowerLimitsRequest function |
| TEST_F(GpuMctpVdmTests, EncodeSetPowerLimitsRequestSuccess) |
| { |
| const uint8_t instanceId = 1; |
| const uint32_t powerLimitId = 0; |
| const gpu::SetPowerLimitsAction action = |
| gpu::SetPowerLimitsAction::NEW_LIMIT; |
| const gpu::SetPowerLimitsPersistence persistence = |
| gpu::SetPowerLimitsPersistence::ONE_SHOT; |
| const uint32_t powerLimitMilliwatts = 500000; |
| std::array<uint8_t, gpu::setPowerLimitsRequestSize> buf{}; |
| |
| int result = gpu::encodeSetPowerLimitsRequest( |
| instanceId, powerLimitId, action, persistence, powerLimitMilliwatts, |
| buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_POWER_LIMITS)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(powerLimitId) + sizeof(uint8_t) + |
| sizeof(uint8_t) + sizeof(powerLimitMilliwatts)); |
| uint32_t unpackedPowerLimitId = 0; |
| ubuf.unpack(unpackedPowerLimitId); |
| EXPECT_EQ(unpackedPowerLimitId, powerLimitId); |
| uint8_t unpackedAction = 0; |
| ubuf.unpack(unpackedAction); |
| EXPECT_EQ(unpackedAction, static_cast<uint8_t>(action)); |
| uint8_t unpackedPersistence = 0; |
| ubuf.unpack(unpackedPersistence); |
| EXPECT_EQ(unpackedPersistence, static_cast<uint8_t>(persistence)); |
| uint32_t unpackedPowerLimit = 0; |
| ubuf.unpack(unpackedPowerLimit); |
| EXPECT_EQ(unpackedPowerLimit, powerLimitMilliwatts); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetPowerLimitsRequestBufferTooSmall) |
| { |
| const uint8_t instanceId = 1; |
| const uint32_t powerLimitId = 0; |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeSetPowerLimitsRequest( |
| instanceId, powerLimitId, gpu::SetPowerLimitsAction::NEW_LIMIT, |
| gpu::SetPowerLimitsPersistence::ONE_SHOT, 500000, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeSetPowerLimitsResponse function |
| TEST_F(GpuMctpVdmTests, DecodeSetPowerLimitsResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_POWER_LIMITS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetPowerLimitsResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetPowerLimitsResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_POWER_LIMITS)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetPowerLimitsResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetPowerLimitsResponseBufferTooSmall) |
| { |
| std::array<uint8_t, 4> buf{}; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetPowerLimitsResponse(buf, cc, reasonCode); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeQueryScalarGroupTelemetryV1RequestSuccess) |
| { |
| const uint8_t instanceId = 10; |
| const uint8_t deviceIndex = 0; |
| const gpu::PcieScalarGroupId groupId = |
| gpu::PcieScalarGroupId::LinkSpeedWidth; |
| std::array<uint8_t, gpu::queryScalarGroupTelemetryV1RequestSize> buf{}; |
| |
| int result = gpu::encodeQueryScalarGroupTelemetryV1Request( |
| instanceId, deviceIndex, groupId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV1)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 2); |
| uint8_t unpackedDeviceIndex = 0; |
| ubuf.unpack(unpackedDeviceIndex); |
| EXPECT_EQ(unpackedDeviceIndex, deviceIndex); |
| uint8_t unpackedGroupId = 0; |
| ubuf.unpack(unpackedGroupId); |
| EXPECT_EQ(unpackedGroupId, static_cast<uint8_t>(groupId)); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeQueryScalarGroupTelemetryV1RequestInvalidSize) |
| { |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeQueryScalarGroupTelemetryV1Request( |
| 0, 0, gpu::PcieScalarGroupId::LinkSpeedWidth, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeQueryScalarGroupTelemetryV2RequestSuccess) |
| { |
| const uint8_t instanceId = 10; |
| const gpu::PciePortType portType = gpu::PciePortType::DOWNSTREAM; |
| const uint8_t upstreamPortNumber = 3; |
| const uint8_t portNumber = 5; |
| const gpu::PcieScalarGroupId groupId = |
| gpu::PcieScalarGroupId::AerErrorCounters; |
| std::array<uint8_t, gpu::queryScalarGroupTelemetryV2RequestSize> buf{}; |
| |
| int result = gpu::encodeQueryScalarGroupTelemetryV2Request( |
| instanceId, portType, upstreamPortNumber, portNumber, groupId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV2)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 3); |
| uint8_t unpackedUpstream = 0; |
| ubuf.unpack(unpackedUpstream); |
| EXPECT_EQ(unpackedUpstream, (static_cast<uint8_t>(portType) << 7) | |
| (upstreamPortNumber & 0x7F)); |
| uint8_t unpackedPortNumber = 0; |
| ubuf.unpack(unpackedPortNumber); |
| EXPECT_EQ(unpackedPortNumber, portNumber); |
| uint8_t unpackedGroupId = 0; |
| ubuf.unpack(unpackedGroupId); |
| EXPECT_EQ(unpackedGroupId, static_cast<uint8_t>(groupId)); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeQueryScalarGroupTelemetryV2RequestInvalidSize) |
| { |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeQueryScalarGroupTelemetryV2Request( |
| 0, {}, 0, 0, gpu::PcieScalarGroupId::LinkSpeedWidth, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV1ResponseSuccess) |
| { |
| const size_t numValues = 4; |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV1)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(numValues * sizeof(uint32_t))); // data_size |
| for (size_t i = 0; i < numValues; ++i) |
| { |
| pbuf.pack(static_cast<uint32_t>((i + 1) * 100)); |
| } |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV1Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(numTelemetryValues, numValues); |
| ASSERT_EQ(telemetryValues.size(), numValues); |
| EXPECT_EQ(telemetryValues[0], 100U); |
| EXPECT_EQ(telemetryValues[1], 200U); |
| EXPECT_EQ(telemetryValues[2], 300U); |
| EXPECT_EQ(telemetryValues[3], 400U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV1ResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV1)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV1Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV1ResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(7); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV1Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV2ResponseSuccess) |
| { |
| const size_t numValues = 4; |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV2)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(numValues * sizeof(uint32_t))); // data_size |
| |
| for (size_t i = 0; i < numValues; ++i) |
| { |
| pbuf.pack(static_cast<uint32_t>((i + 1) * 100)); |
| } |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV2Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(numTelemetryValues, numValues); |
| ASSERT_EQ(telemetryValues.size(), numValues); |
| EXPECT_EQ(telemetryValues[0], 100U); |
| EXPECT_EQ(telemetryValues[1], 200U); |
| EXPECT_EQ(telemetryValues[2], 300U); |
| EXPECT_EQ(telemetryValues[3], 400U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV2ResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PcieLinkCommands::QueryScalarGroupTelemetryV2)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x5678)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV2Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeQueryScalarGroupTelemetryV2ResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(7); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 10, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| size_t numTelemetryValues{}; |
| std::vector<uint32_t> telemetryValues{}; |
| |
| int result = gpu::decodeQueryScalarGroupTelemetryV2Response( |
| buf, cc, reasonCode, numTelemetryValues, telemetryValues); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeListPciePortsRequestSuccess) |
| { |
| const uint8_t instanceId = 11; |
| std::array<uint8_t, ocp::accelerator_management::commonRequestSize> buf{}; |
| |
| int result = gpu::encodeListPciePortsRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>(gpu::PcieLinkCommands::ListPCIePorts)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeListPciePortsResponseSuccess) |
| { |
| const size_t totalUpstreamPorts = 2; |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 11, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack( |
| static_cast<uint8_t>(gpu::PcieLinkCommands::ListPCIePorts)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>( |
| sizeof(uint16_t) + |
| totalUpstreamPorts * 2 * sizeof(uint8_t))); // data_size |
| pbuf.pack(static_cast<uint16_t>(totalUpstreamPorts)); |
| // Port 0: external, 4 downstream |
| pbuf.pack(static_cast<uint8_t>(0)); // isInternal |
| pbuf.pack(static_cast<uint8_t>(4)); // count |
| // Port 1: internal, 2 downstream |
| pbuf.pack(static_cast<uint8_t>(1)); // isInternal |
| pbuf.pack(static_cast<uint8_t>(2)); // count |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t numUpstreamPorts{}; |
| std::vector<uint8_t> numDownstreamPorts{}; |
| |
| int result = gpu::decodeListPciePortsResponse( |
| buf, cc, reasonCode, numUpstreamPorts, numDownstreamPorts); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(numUpstreamPorts, 1); |
| ASSERT_EQ(numDownstreamPorts.size(), 1); |
| EXPECT_EQ(numDownstreamPorts[0], 4); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeListPciePortsResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 11, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack( |
| static_cast<uint8_t>(gpu::PcieLinkCommands::ListPCIePorts)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xBEEF)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t numUpstreamPorts{}; |
| std::vector<uint8_t> numDownstreamPorts{}; |
| |
| int result = gpu::decodeListPciePortsResponse( |
| buf, cc, reasonCode, numUpstreamPorts, numDownstreamPorts); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xBEEF); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeListPciePortsResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 11, |
| static_cast<uint8_t>(gpu::MessageType::PCIE_LINK)); |
| pbuf.pack( |
| static_cast<uint8_t>(gpu::PcieLinkCommands::ListPCIePorts)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(1)); // Invalid data_size |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t numUpstreamPorts{}; |
| std::vector<uint8_t> numDownstreamPorts{}; |
| |
| int result = gpu::decodeListPciePortsResponse( |
| buf, cc, reasonCode, numUpstreamPorts, numDownstreamPorts); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeAggregateResponse function |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponsePowerOf2LengthEncodingValid) |
| { |
| // Test with power-of-2 length encoding and valid bit set |
| std::vector<uint8_t> buf = { |
| 0x03, 0x00, // telemetryCount = 3 (little-endian) |
| // Item 0: tag=0x01, tagInfo=0x05 (power-of-2, valueLength=2, valid=1) |
| // length = 1 << 2 = 4 bytes |
| 0x01, 0x05, 0x11, 0x22, 0x33, 0x44, |
| // Item 1: tag=0x02, tagInfo=0x07 (power-of-2, valueLength=3, valid=1) |
| // length = 1 << 3 = 8 bytes |
| 0x02, 0x07, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, |
| // Item 2: tag=0x03, tagInfo=0x01 (power-of-2, valueLength=0, valid=1) |
| // length = 1 << 0 = 1 byte |
| 0x03, 0x01, 0x55}; |
| |
| UnpackBuffer buffer(buf); |
| |
| struct HandlerData |
| { |
| std::vector<uint8_t> tags; |
| std::vector<uint8_t> lengths; |
| std::vector<std::vector<uint8_t>> values; |
| } handlerData; |
| |
| auto handler = [&handlerData](const uint8_t tag, const uint8_t length, |
| UnpackBuffer& buffer) -> int { |
| handlerData.tags.push_back(tag); |
| handlerData.lengths.push_back(length); |
| std::vector<uint8_t> value(length); |
| for (uint8_t i = 0; i < length; ++i) |
| { |
| uint8_t byte = 0; |
| int rc = buffer.unpack(byte); |
| if (rc != 0) |
| { |
| return rc; |
| } |
| value[i] = byte; |
| } |
| handlerData.values.push_back(std::move(value)); |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, 0); |
| |
| // Verify 3 items were processed |
| EXPECT_EQ(handlerData.tags.size(), 3U); |
| |
| // Verify item 0: tag=0x01, length=4 |
| EXPECT_EQ(handlerData.tags[0], 0x01); |
| EXPECT_EQ(handlerData.lengths[0], 4); |
| EXPECT_EQ(handlerData.values[0].size(), 4U); |
| EXPECT_EQ(handlerData.values[0][0], 0x11); |
| EXPECT_EQ(handlerData.values[0][1], 0x22); |
| EXPECT_EQ(handlerData.values[0][2], 0x33); |
| EXPECT_EQ(handlerData.values[0][3], 0x44); |
| |
| // Verify item 1: tag=0x02, length=8 |
| EXPECT_EQ(handlerData.tags[1], 0x02); |
| EXPECT_EQ(handlerData.lengths[1], 8); |
| EXPECT_EQ(handlerData.values[1].size(), 8U); |
| EXPECT_EQ(handlerData.values[1][0], 0xAA); |
| EXPECT_EQ(handlerData.values[1][7], 0x11); |
| |
| // Verify item 2: tag=0x03, length=1 |
| EXPECT_EQ(handlerData.tags[2], 0x03); |
| EXPECT_EQ(handlerData.lengths[2], 1); |
| EXPECT_EQ(handlerData.values[2].size(), 1U); |
| EXPECT_EQ(handlerData.values[2][0], 0x55); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseByteLengthEncodingValid) |
| { |
| // Test with byte length encoding and valid bit set |
| std::vector<uint8_t> buf = { |
| 0x02, 0x00, // telemetryCount = 2 (little-endian) |
| // Item 0: tag=0x10, tagInfo=0x85 (byte-length, valueLength=2, valid=1) |
| // bit 7=1 (byte-length), bits 3-1=010 (valueLength=2), bit 0=1 (valid) |
| // length = 2 bytes |
| 0x10, 0x85, 0xAA, 0xBB, |
| // Item 1: tag=0x11, tagInfo=0x8B (byte-length, valueLength=5, valid=1) |
| // bit 7=1 (byte-length), bits 3-1=101 (valueLength=5), bit 0=1 (valid) |
| // length = 5 bytes |
| 0x11, 0x8B, 0x01, 0x02, 0x03, 0x04, 0x05}; |
| |
| UnpackBuffer buffer(buf); |
| |
| struct HandlerData |
| { |
| std::vector<uint8_t> tags; |
| std::vector<uint8_t> lengths; |
| std::vector<std::vector<uint8_t>> values; |
| } handlerData; |
| |
| auto handler = [&handlerData](const uint8_t tag, const uint8_t length, |
| UnpackBuffer& buffer) -> int { |
| handlerData.tags.push_back(tag); |
| handlerData.lengths.push_back(length); |
| std::vector<uint8_t> value(length); |
| for (uint8_t i = 0; i < length; ++i) |
| { |
| uint8_t byte = 0; |
| int rc = buffer.unpack(byte); |
| if (rc != 0) |
| { |
| return rc; |
| } |
| value[i] = byte; |
| } |
| handlerData.values.push_back(std::move(value)); |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, 0); |
| |
| // Verify 2 items were processed |
| EXPECT_EQ(handlerData.tags.size(), 2U); |
| |
| // Verify item 0: tag=0x10, length=2 |
| EXPECT_EQ(handlerData.tags[0], 0x10); |
| EXPECT_EQ(handlerData.lengths[0], 2); |
| EXPECT_EQ(handlerData.values[0].size(), 2U); |
| EXPECT_EQ(handlerData.values[0][0], 0xAA); |
| EXPECT_EQ(handlerData.values[0][1], 0xBB); |
| |
| // Verify item 1: tag=0x11, length=5 |
| EXPECT_EQ(handlerData.tags[1], 0x11); |
| EXPECT_EQ(handlerData.lengths[1], 5); |
| EXPECT_EQ(handlerData.values[1].size(), 5U); |
| EXPECT_EQ(handlerData.values[1][0], 0x01); |
| EXPECT_EQ(handlerData.values[1][4], 0x05); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseInvalidBitNotSet) |
| { |
| // Test with valid bit NOT set - items should be skipped |
| std::vector<uint8_t> buf = { |
| 0x03, 0x00, // telemetryCount = 3 |
| // Item 0: tag=0x01, tagInfo=0x05 (valid bit set) |
| 0x01, 0x05, 0x11, 0x22, 0x33, 0x44, |
| // Item 1: tag=0x02, tagInfo=0x06 (valid bit NOT set - bit 0 = 0) |
| // This should be skipped |
| 0x02, 0x06, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, |
| // Item 2: tag=0x03, tagInfo=0x01 (valid bit set) |
| 0x03, 0x01, 0x55}; |
| |
| UnpackBuffer buffer(buf); |
| |
| struct HandlerData |
| { |
| std::vector<uint8_t> tags; |
| std::vector<uint8_t> lengths; |
| } handlerData; |
| |
| auto handler = [&handlerData](const uint8_t tag, const uint8_t length, |
| UnpackBuffer& buffer) -> int { |
| handlerData.tags.push_back(tag); |
| handlerData.lengths.push_back(length); |
| buffer.skip(length); |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, 0); |
| |
| // Only 2 items should be processed (item 1 skipped because valid bit not |
| // set) |
| EXPECT_EQ(handlerData.tags.size(), 2U); |
| EXPECT_EQ(handlerData.tags[0], 0x01); |
| EXPECT_EQ(handlerData.tags[1], 0x03); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseMixedEncodingAndValidity) |
| { |
| // Test with mixed length encoding types and validity |
| std::vector<uint8_t> buf = { |
| 0x04, 0x00, // telemetryCount = 4 |
| // Item 0: power-of-2, valid |
| 0x01, 0x05, 0x11, 0x22, 0x33, 0x44, |
| // Item 1: byte-length, valid |
| 0x02, 0x83, 0xAA, |
| // Item 2: power-of-2, invalid |
| 0x03, 0x04, 0xCC, 0xDD, 0xEE, 0xFF, |
| // Item 3: byte-length, valid |
| 0x04, 0x89, 0x55, 0x66, 0x77, 0x88}; |
| |
| UnpackBuffer buffer(buf); |
| |
| struct HandlerData |
| { |
| std::vector<uint8_t> tags; |
| std::vector<uint8_t> lengths; |
| } handlerData; |
| |
| auto handler = [&handlerData](const uint8_t tag, const uint8_t length, |
| UnpackBuffer& buffer) -> int { |
| handlerData.tags.push_back(tag); |
| handlerData.lengths.push_back(length); |
| buffer.skip(length); |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, 0); |
| |
| // 3 items should be processed (item 2 skipped) |
| EXPECT_EQ(handlerData.tags.size(), 3U); |
| EXPECT_EQ(handlerData.tags[0], 0x01); |
| EXPECT_EQ(handlerData.lengths[0], 4); // power-of-2: 1 << 2 = 4 |
| EXPECT_EQ(handlerData.tags[1], 0x02); |
| EXPECT_EQ(handlerData.lengths[1], 1); // byte-length: 1 |
| EXPECT_EQ(handlerData.tags[2], 0x04); |
| EXPECT_EQ(handlerData.lengths[2], 4); // byte-length: 4 |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseHandlerError) |
| { |
| // Test that handler returning error stops processing |
| std::vector<uint8_t> buf = { |
| 0x02, 0x00, // telemetryCount = 2 |
| // Item 0: tag=0x01, tagInfo=0x01 (power-of-2, |
| // valueLength=0, valid=1) length = 1 byte |
| 0x01, 0x01, 0xAA, |
| // Item 1: tag=0x02, tagInfo=0x01 |
| 0x02, 0x01, 0xBB}; |
| |
| UnpackBuffer buffer(buf); |
| |
| int handlerCallCount = 0; |
| auto handler = [&handlerCallCount](const uint8_t, const uint8_t length, |
| UnpackBuffer& buffer) -> int { |
| handlerCallCount++; |
| buffer.skip(length); |
| return ENOTSUP; // Return error on first call |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, ENOTSUP); |
| EXPECT_EQ(handlerCallCount, 1); // Only first item processed before error |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseInvalidBufferSize) |
| { |
| // Test with buffer too small - missing second byte of telemetryCount |
| std::vector<uint8_t> buf = { |
| 0x01 // Truncated - missing second byte of telemetryCount |
| }; |
| |
| UnpackBuffer buffer(buf); |
| |
| auto handler = [](const uint8_t, const uint8_t, UnpackBuffer&) -> int { |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeAggregateResponseEmptyItems) |
| { |
| // Test with zero items |
| std::vector<uint8_t> buf = { |
| 0x00, 0x00 // telemetryCount = 0 |
| }; |
| |
| UnpackBuffer buffer(buf); |
| |
| int handlerCallCount = 0; |
| auto handler = [&handlerCallCount](const uint8_t, const uint8_t, |
| UnpackBuffer&) -> int { |
| handlerCallCount++; |
| return 0; |
| }; |
| |
| int result = ocp::accelerator_management::unpackAggregateResponse( |
| buffer, std::move(handler)); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(handlerCallCount, 0); // No items to process |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetPortNetworkAddressesRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetPortNetworkAddressesRequestSuccess) |
| { |
| const uint8_t instanceId = 12; |
| const uint16_t portNumber = 5; |
| std::array<uint8_t, gpu::getPortNetworkAddressesRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeGetPortNetworkAddressesRequest(instanceId, portNumber, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::NETWORK_PORT)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>( |
| gpu::NetworkPortCommands::GetPortNetworkAddresses)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 2); |
| uint16_t unpackedPortNumber = 0; |
| ubuf.unpack(unpackedPortNumber); |
| EXPECT_EQ(unpackedPortNumber, portNumber); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetPortNetworkAddressesRequestInvalidBufferSize) |
| { |
| const uint8_t instanceId = 12; |
| const uint16_t portNumber = 5; |
| std::array<uint8_t, gpu::getPortNetworkAddressesRequestSize - 1> buf{}; |
| |
| int result = |
| gpu::encodeGetPortNetworkAddressesRequest(instanceId, portNumber, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetPortNetworkAddressesResponse function |
| TEST_F(GpuMctpVdmTests, DecodeGetPortNetworkAddressesResponseSuccess) |
| { |
| // Test with linkType and two MAC addresses |
| std::vector<uint8_t> buf = { |
| 0x10, 0xde, 0x00, 0x89, 0x01, 0x11, // Message header |
| 0x00, // completion_code (SUCCESS) |
| 0x03, 0x00, // telemetryCount = 3 |
| // Item 0: tag=0x00, tagInfo=0x01 (power-of-2, valueLength=0, valid=1) |
| // length = 1 << 0 = 1 byte |
| 0x00, 0x01, 0x00, // linkType = ETHERNET (0) |
| // Item 1: tag=0x01, tagInfo=0x07 (power-of-2, valueLength=3, valid=1) |
| // length = 1 << 3 = 8 bytes (uint64_t MAC address) |
| 0x01, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, |
| // Item 2: tag=0x02, tagInfo=0x07 (power-of-2, valueLength=3, valid=1) |
| // length = 8 bytes (uint64_t MAC address) |
| 0x02, 0x07, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11}; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::NetworkPortLinkType linkType{}; |
| std::vector<std::pair<uint8_t, uint64_t>> addresses{}; |
| |
| int result = gpu::decodeGetPortNetworkAddressesResponse( |
| buf, cc, reasonCode, linkType, addresses); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(linkType, gpu::NetworkPortLinkType::ETHERNET); |
| EXPECT_EQ(addresses.size(), 2U); |
| |
| // Verify first address (tag=0x01) |
| EXPECT_EQ(addresses[0].first, 0x01); |
| EXPECT_EQ(addresses[0].second, 0x0807060504030201ULL); |
| |
| // Verify second address (tag=0x02) |
| EXPECT_EQ(addresses[1].first, 0x02); |
| EXPECT_EQ(addresses[1].second, 0x11100F0E0D0C0B0AULL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetPortNetworkAddressesResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 12, |
| static_cast<uint8_t>(gpu::MessageType::NETWORK_PORT)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::NetworkPortCommands::GetPortNetworkAddresses)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xABCD)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::NetworkPortLinkType linkType{}; |
| std::vector<std::pair<uint8_t, uint64_t>> addresses{}; |
| |
| int result = gpu::decodeGetPortNetworkAddressesResponse( |
| buf, cc, reasonCode, linkType, addresses); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xABCD); |
| EXPECT_EQ(addresses.size(), 0U); // Should be empty on error |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetPortNetworkAddressesResponseInvalidBufferSize) |
| { |
| // Buffer too small - missing telemetryCount |
| std::vector<uint8_t> buf = { |
| 0x10, 0xde, 0x00, 0x89, 0x01, 0x0f, // Message header |
| 0x00, // completion_code |
| 0x01 // Truncated - missing second byte of telemetryCount |
| }; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| gpu::NetworkPortLinkType linkType{}; |
| std::vector<std::pair<uint8_t, uint64_t>> addresses{}; |
| |
| int result = gpu::decodeGetPortNetworkAddressesResponse( |
| buf, cc, reasonCode, linkType, addresses); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::encodeGetEthernetPortTelemetryCountersRequest function |
| TEST_F(GpuMctpVdmTests, EncodeGetEthernetPortTelemetryCountersRequestSuccess) |
| { |
| const uint8_t instanceId = 13; |
| const uint16_t portNumber = 7; |
| std::array<uint8_t, gpu::getEthernetPortTelemetryCountersRequestSize> buf{}; |
| |
| int result = gpu::encodeGetEthernetPortTelemetryCountersRequest( |
| instanceId, portNumber, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::NETWORK_PORT)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::NetworkPortCommands::GetEthernetPortTelemetryCounters)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 2); |
| uint16_t unpackedPortNumber = 0; |
| ubuf.unpack(unpackedPortNumber); |
| EXPECT_EQ(unpackedPortNumber, portNumber); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| EncodeGetEthernetPortTelemetryCountersRequestInvalidBufferSize) |
| { |
| const uint8_t instanceId = 13; |
| const uint16_t portNumber = 7; |
| std::array<uint8_t, gpu::getEthernetPortTelemetryCountersRequestSize - 1> |
| buf{}; |
| |
| int result = gpu::encodeGetEthernetPortTelemetryCountersRequest( |
| instanceId, portNumber, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for GpuMctpVdm::decodeGetEthernetPortTelemetryCountersResponse |
| // function |
| TEST_F(GpuMctpVdmTests, DecodeGetEthernetPortTelemetryCountersResponseSuccess) |
| { |
| // Test with mixed uint32_t and uint64_t telemetry values |
| std::vector<uint8_t> buf = { |
| 0x10, 0xde, 0x00, 0x89, 0x01, 0x0f, // Message header |
| 0x00, // completion_code (SUCCESS) |
| 0x03, 0x00, // telemetryCount = 3 |
| // Item 0: tag=0x01, tagInfo=0x05 (power-of-2, valueLength=2, valid=1) |
| // length = 1 << 2 = 4 bytes (uint32_t) |
| 0x01, 0x05, 0x64, 0x00, 0x00, 0x00, // value = 100 |
| // Item 1: tag=0x02, tagInfo=0x07 (power-of-2, valueLength=3, valid=1) |
| // length = 1 << 3 = 8 bytes (uint64_t) |
| 0x02, 0x07, 0xE8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, // value = 1000 |
| // Item 2: tag=0x03, tagInfo=0x05 (power-of-2, valueLength=2, valid=1) |
| // length = 4 bytes (uint32_t) |
| 0x03, 0x05, 0x10, 0x27, 0x00, 0x00 // value = 10000 |
| }; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<std::pair<uint8_t, uint64_t>> telemetryValues{}; |
| |
| int result = gpu::decodeGetEthernetPortTelemetryCountersResponse( |
| buf, cc, reasonCode, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(telemetryValues.size(), 3U); |
| |
| // Verify first value (tag=0x01, uint32_t) |
| EXPECT_EQ(telemetryValues[0].first, 0x01); |
| EXPECT_EQ(telemetryValues[0].second, 100U); |
| |
| // Verify second value (tag=0x02, uint64_t) |
| EXPECT_EQ(telemetryValues[1].first, 0x02); |
| EXPECT_EQ(telemetryValues[1].second, 1000U); |
| |
| // Verify third value (tag=0x03, uint32_t) |
| EXPECT_EQ(telemetryValues[2].first, 0x03); |
| EXPECT_EQ(telemetryValues[2].second, 10000U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetEthernetPortTelemetryCountersResponseSkipInvalidLengths) |
| { |
| // Test that values with invalid lengths are skipped |
| std::vector<uint8_t> buf = { |
| 0x10, 0xde, 0x00, 0x89, 0x01, 0x0f, // Message header |
| 0x00, // completion_code (SUCCESS) |
| 0x03, 0x00, // telemetryCount = 3 |
| // Item 0: tag=0x01, tagInfo=0x05 (valid, length=4) |
| 0x01, 0x05, 0x64, 0x00, 0x00, 0x00, |
| // Item 1: tag=0x02, tagInfo=0x03 (valid, length=2 - invalid, will be |
| // skipped) |
| 0x02, 0x03, 0xAA, 0xBB, |
| // Item 2: tag=0x03, tagInfo=0x07 (valid, length=8) |
| 0x03, 0x07, 0xE8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<std::pair<uint8_t, uint64_t>> telemetryValues{}; |
| |
| int result = gpu::decodeGetEthernetPortTelemetryCountersResponse( |
| buf, cc, reasonCode, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| // Only 2 items should be present (item 1 skipped due to invalid length) |
| EXPECT_EQ(telemetryValues.size(), 2U); |
| |
| EXPECT_EQ(telemetryValues[0].first, 0x01); |
| EXPECT_EQ(telemetryValues[0].second, 100U); |
| |
| EXPECT_EQ(telemetryValues[1].first, 0x03); |
| EXPECT_EQ(telemetryValues[1].second, 1000U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEthernetPortTelemetryCountersResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 13, |
| static_cast<uint8_t>(gpu::MessageType::NETWORK_PORT)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::NetworkPortCommands::GetEthernetPortTelemetryCounters)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xDEAD)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<std::pair<uint8_t, uint64_t>> telemetryValues{}; |
| |
| int result = gpu::decodeGetEthernetPortTelemetryCountersResponse( |
| buf, cc, reasonCode, telemetryValues); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xDEAD); |
| EXPECT_EQ(telemetryValues.size(), 0U); // Should be empty on error |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetEthernetPortTelemetryCountersResponseInvalidBufferSize) |
| { |
| // Buffer too small |
| std::vector<uint8_t> buf = { |
| 0x10, 0xde, 0x00, 0x89, 0x01, 0x0f, // Message header |
| 0x00, // completion_code |
| 0x01 // Truncated - missing second byte of telemetryCount |
| }; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<std::pair<uint8_t, uint64_t>> telemetryValues{}; |
| |
| int result = gpu::decodeGetEthernetPortTelemetryCountersResponse( |
| buf, cc, reasonCode, telemetryValues); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Helper: pack a CommonNonSuccessResponse using PackBuffer |
| // Layout: BindingPciVid(5) + command(1) + completion_code(1) + reason_code(2) |
| void packNonSuccessResponse(PackBuffer& packer, uint8_t command, |
| uint8_t completionCode, uint16_t reasonCode) |
| { |
| // BindingPciVid header for response |
| // pci_vendor_id (big-endian) |
| packer.pack(static_cast<uint16_t>(htobe16(gpu::nvidiaPciVendorId))); |
| // instance_id: response (bit 7 clear), instance=0 |
| packer.pack(static_cast<uint8_t>(0x00)); |
| // ocp_version: type=8 (upper nibble), version=9 (lower nibble) |
| packer.pack(static_cast<uint8_t>(0x89)); |
| // ocp_accelerator_management_msg_type = DEVICE_CAPABILITY_DISCOVERY = 0 |
| packer.pack( |
| static_cast<uint8_t>(gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| |
| packer.pack(command); |
| packer.pack(completionCode); |
| packer.pack(reasonCode); // little-endian by PackBuffer |
| } |
| |
| // Tests for gpu::encodeSetEventSubscriptionRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetEventSubscriptionRequestSuccess) |
| { |
| // SetEventSubscriptionRequest: CommonRequest(7) + |
| // generation_setting(1) + receiver_setting(1) = 9 bytes |
| std::vector<uint8_t> buf(256); |
| |
| const uint8_t eid = 0x42; |
| int result = gpu::encodeSetEventSubscriptionRequest(2, eid, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer unpacker(std::span<const uint8_t>(buf.data(), 9)); |
| |
| // BindingPciVid header |
| uint16_t pciVendorId{}; |
| uint8_t instanceId{}; |
| uint8_t ocpVersion{}; |
| uint8_t msgType{}; |
| unpacker.unpack(pciVendorId); |
| unpacker.unpack(instanceId); |
| unpacker.unpack(ocpVersion); |
| unpacker.unpack(msgType); |
| |
| EXPECT_EQ(pciVendorId, htobe16(gpu::nvidiaPciVendorId)); |
| EXPECT_NE(instanceId & ocp::accelerator_management::requestBitMask, 0); |
| EXPECT_EQ(ocpVersion & ocp::accelerator_management::ocpVersionBitMask, |
| ocp::accelerator_management::ocpVersion); |
| EXPECT_EQ((ocpVersion & ocp::accelerator_management::ocpTypeBitMask) >> |
| ocp::accelerator_management::ocpTypeBitOffset, |
| ocp::accelerator_management::ocpType); |
| EXPECT_EQ(msgType, static_cast<uint8_t>( |
| gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| |
| // CommonRequest fields |
| uint8_t command{}; |
| uint8_t dataSize{}; |
| unpacker.unpack(command); |
| unpacker.unpack(dataSize); |
| |
| EXPECT_EQ( |
| command, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_EVENT_SUBSCRIPTION)); |
| EXPECT_EQ(dataSize, 2); |
| |
| // Payload: generation_setting + receiver_setting |
| uint8_t generationSetting{}; |
| uint8_t receiverSetting{}; |
| unpacker.unpack(generationSetting); |
| unpacker.unpack(receiverSetting); |
| |
| EXPECT_EQ(unpacker.getError(), 0); |
| EXPECT_EQ(generationSetting, 2); |
| EXPECT_EQ(receiverSetting, eid); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetEventSubscriptionRequestBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(5); // Too small for 9-byte request |
| int result = gpu::encodeSetEventSubscriptionRequest(2, 0x42, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeSetEventSubscriptionResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSubscriptionResponseSuccess) |
| { |
| // CommonNonSuccessResponse: BindingPciVid(5) + command(1) + cc(1) + |
| // reason_code(2) = 9 bytes |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packNonSuccessResponse( |
| packer, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_EVENT_SUBSCRIPTION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSubscriptionResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSubscriptionResponseError) |
| { |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packNonSuccessResponse( |
| packer, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_EVENT_SUBSCRIPTION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR), |
| 0x1234); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSubscriptionResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSubscriptionResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(4); // Too small for 9-byte response |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSubscriptionResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::encodeSetEventSourcesRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetEventSourcesRequestSuccess) |
| { |
| // SetEventSourcesRequest: CommonRequest(7) + |
| // messageType(1) + sources(8) = 16 bytes |
| std::vector<uint8_t> buf(256); |
| |
| const uint64_t sources = 0xDEADBEEFCAFE0123; |
| const uint8_t messageType = 3; // PLATFORM_ENVIRONMENTAL |
| int result = gpu::encodeSetEventSourcesRequest(sources, messageType, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer unpacker(std::span<const uint8_t>(buf.data(), 16)); |
| |
| // BindingPciVid header |
| uint16_t pciVendorId{}; |
| uint8_t instanceId{}; |
| uint8_t ocpVersion{}; |
| uint8_t msgType{}; |
| unpacker.unpack(pciVendorId); |
| unpacker.unpack(instanceId); |
| unpacker.unpack(ocpVersion); |
| unpacker.unpack(msgType); |
| |
| EXPECT_EQ(pciVendorId, htobe16(gpu::nvidiaPciVendorId)); |
| EXPECT_NE(instanceId & ocp::accelerator_management::requestBitMask, 0); |
| EXPECT_EQ(msgType, static_cast<uint8_t>( |
| gpu::MessageType::DEVICE_CAPABILITY_DISCOVERY)); |
| |
| // CommonRequest fields |
| uint8_t command{}; |
| uint8_t dataSize{}; |
| unpacker.unpack(command); |
| unpacker.unpack(dataSize); |
| |
| EXPECT_EQ( |
| command, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_CURRENT_EVENT_SOURCES)); |
| EXPECT_EQ(dataSize, 9); |
| |
| // Payload: messageType + sources |
| uint8_t decodedMessageType{}; |
| uint64_t decodedSources{}; |
| unpacker.unpack(decodedMessageType); |
| unpacker.unpack(decodedSources); |
| |
| EXPECT_EQ(unpacker.getError(), 0); |
| EXPECT_EQ(decodedMessageType, messageType); |
| EXPECT_EQ(decodedSources, sources); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetEventSourcesRequestBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(5); // Too small for 16-byte request |
| int result = gpu::encodeSetEventSourcesRequest(0x1, 3, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeSetEventSourcesResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSourcesResponseSuccess) |
| { |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packNonSuccessResponse( |
| packer, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_CURRENT_EVENT_SOURCES), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSourcesResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSourcesResponseError) |
| { |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packNonSuccessResponse( |
| packer, |
| static_cast<uint8_t>( |
| gpu::DeviceCapabilityDiscoveryCommands::SET_CURRENT_EVENT_SOURCES), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR), |
| 0x1234); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSourcesResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetEventSourcesResponseInvalidSize) |
| { |
| std::vector<uint8_t> buf(4); // Too small for 9-byte response |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetEventSourcesResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::encodeGetCurrentUtilizationModeRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentUtilizationModeRequestSuccess) |
| { |
| const uint8_t instanceId = 5; |
| std::vector<uint8_t> buf(256); |
| |
| int result = gpu::encodeGetCurrentUtilizationModeRequest(instanceId, buf); |
| EXPECT_EQ(result, 0); |
| |
| // CommonRequest: BindingPciVid(5) + command(1) + data_size(1) = 7 bytes |
| UnpackBuffer unpacker(std::span<const uint8_t>(buf.data(), 7)); |
| |
| // BindingPciVid header |
| uint16_t pciVendorId{}; |
| uint8_t instId{}; |
| uint8_t ocpVersion{}; |
| uint8_t msgType{}; |
| unpacker.unpack(pciVendorId); |
| unpacker.unpack(instId); |
| unpacker.unpack(ocpVersion); |
| unpacker.unpack(msgType); |
| |
| EXPECT_EQ(pciVendorId, htobe16(gpu::nvidiaPciVendorId)); |
| EXPECT_EQ(instId & ocp::accelerator_management::instanceIdBitMask, |
| instanceId); |
| EXPECT_NE(instId & ocp::accelerator_management::requestBitMask, 0); |
| EXPECT_EQ(ocpVersion & ocp::accelerator_management::ocpVersionBitMask, |
| ocp::accelerator_management::ocpVersion); |
| EXPECT_EQ((ocpVersion & ocp::accelerator_management::ocpTypeBitMask) >> |
| ocp::accelerator_management::ocpTypeBitOffset, |
| ocp::accelerator_management::ocpType); |
| EXPECT_EQ(msgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| // CommonRequest fields |
| uint8_t command{}; |
| uint8_t dataSize{}; |
| unpacker.unpack(command); |
| unpacker.unpack(dataSize); |
| |
| EXPECT_EQ(unpacker.getError(), 0); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION)); |
| EXPECT_EQ(dataSize, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentUtilizationModeRequestBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(3); // Too small for 7-byte request |
| int result = gpu::encodeGetCurrentUtilizationModeRequest(0, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeLongRunningResponseEvent |
| |
| TEST_F(GpuMctpVdmTests, DecodeLongRunningResponseEventSuccess) |
| { |
| // LongRunningResponseEvent: instanceId(1) + completionCode(1) + |
| // reasonCode(2) = 4 bytes |
| std::vector<uint8_t> buf(4); |
| PackBuffer packer(buf); |
| |
| packer.pack(static_cast<uint8_t>(7)); // instanceId |
| packer.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // cc |
| packer.pack(static_cast<uint16_t>(0)); // reasonCode |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t instanceId{}; |
| std::span<const uint8_t> responseData; |
| |
| int result = gpu::decodeLongRunningResponseEvent(buf, cc, reasonCode, |
| instanceId, responseData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(instanceId, 7); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_TRUE(responseData.empty()); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeLongRunningResponseEventWithResponseData) |
| { |
| // 4-byte header + 3 bytes response data |
| std::vector<uint8_t> buf(7); |
| PackBuffer packer(buf); |
| |
| packer.pack(static_cast<uint8_t>(2)); // instanceId |
| packer.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // cc |
| packer.pack(static_cast<uint16_t>(0)); // reasonCode |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| // Fill response data |
| buf[4] = 0xAA; |
| buf[5] = 0xBB; |
| buf[6] = 0xCC; |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t instanceId{}; |
| std::span<const uint8_t> responseData; |
| |
| int result = gpu::decodeLongRunningResponseEvent(buf, cc, reasonCode, |
| instanceId, responseData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(instanceId, 2); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| ASSERT_EQ(responseData.size(), 3); |
| EXPECT_EQ(responseData[0], 0xAA); |
| EXPECT_EQ(responseData[1], 0xBB); |
| EXPECT_EQ(responseData[2], 0xCC); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeLongRunningResponseEventError) |
| { |
| std::vector<uint8_t> buf(4); |
| PackBuffer packer(buf); |
| |
| packer.pack(static_cast<uint8_t>(3)); // instanceId |
| packer.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); // cc |
| packer.pack(static_cast<uint16_t>(0x5678)); // reasonCode |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t instanceId{}; |
| std::span<const uint8_t> responseData; |
| |
| int result = gpu::decodeLongRunningResponseEvent(buf, cc, reasonCode, |
| instanceId, responseData); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(instanceId, 3); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeLongRunningResponseEventBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(2); // Too small for 4-byte event |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint8_t instanceId{}; |
| std::span<const uint8_t> responseData; |
| |
| int result = gpu::decodeLongRunningResponseEvent(buf, cc, reasonCode, |
| instanceId, responseData); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventSuccess) |
| { |
| // Buffer: 20-byte header + message text |
| const std::string message = "XID error occurred"; |
| constexpr size_t headerSize = gpu::xidEventMinDataSize; |
| std::vector<uint8_t> buf(headerSize + message.size()); |
| |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint8_t>(0x01)); // flags |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[0] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[1] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[2] |
| packer.pack(static_cast<uint32_t>(42)); // eventMessageReason |
| packer.pack(static_cast<uint32_t>(100)); // sequenceNumber |
| packer.pack(static_cast<uint64_t>(1000000000ULL)); // timestamp |
| ASSERT_EQ(packer.getError(), 0); |
| |
| std::memcpy(buf.data() + headerSize, message.data(), message.size()); |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(flags, 0x01); |
| EXPECT_EQ(eventMessageReason, 42U); |
| EXPECT_EQ(sequenceNumber, 100U); |
| EXPECT_EQ(timestamp, 1000000000ULL); |
| EXPECT_EQ(messageTextString, message); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventMinimumBufferEmptyMessage) |
| { |
| std::vector<uint8_t> buf(gpu::xidEventMinDataSize); |
| |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint8_t>(0xFF)); // flags |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[0] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[1] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[2] |
| packer.pack(static_cast<uint32_t>(0xDEADBEEFU)); // eventMessageReason |
| packer.pack(static_cast<uint32_t>(0xCAFEBABEU)); // sequenceNumber |
| packer.pack(static_cast<uint64_t>(0x123456789ABCDEF0ULL)); // timestamp |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(flags, 0xFF); |
| EXPECT_EQ(eventMessageReason, 0xDEADBEEFU); |
| EXPECT_EQ(sequenceNumber, 0xCAFEBABEU); |
| EXPECT_EQ(timestamp, 0x123456789ABCDEF0ULL); |
| EXPECT_TRUE(messageTextString.empty()); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventZeroValues) |
| { |
| std::vector<uint8_t> buf(gpu::xidEventMinDataSize, 0); |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(flags, 0); |
| EXPECT_EQ(eventMessageReason, 0U); |
| EXPECT_EQ(sequenceNumber, 0U); |
| EXPECT_EQ(timestamp, 0ULL); |
| EXPECT_TRUE(messageTextString.empty()); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(gpu::xidEventMinDataSize - 1); |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventEmptyBuffer) |
| { |
| // Zero-length buffer — must return EINVAL immediately |
| std::vector<uint8_t> buf; |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeXidEventMessageTextPointsIntoBuffer) |
| { |
| // Verify that string_view returned by decodeXidEvent points directly into |
| // the original buffer (zero-copy) rather than a copy. |
| const std::string message = "GPU fault"; |
| std::vector<uint8_t> buf(gpu::xidEventMinDataSize + message.size()); |
| |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint8_t>(0x00)); // flags |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[0] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[1] |
| packer.pack(static_cast<uint8_t>(0x00)); // reserved[2] |
| packer.pack(static_cast<uint32_t>(7U)); // eventMessageReason |
| packer.pack(static_cast<uint32_t>(3U)); // sequenceNumber |
| packer.pack(static_cast<uint64_t>(42ULL)); // timestamp |
| ASSERT_EQ(packer.getError(), 0); |
| |
| std::memcpy(buf.data() + gpu::xidEventMinDataSize, message.data(), |
| message.size()); |
| |
| uint8_t flags{}; |
| uint32_t eventMessageReason{}; |
| uint32_t sequenceNumber{}; |
| uint64_t timestamp{}; |
| std::string_view messageTextString{}; |
| |
| int result = |
| gpu::decodeXidEvent(buf, flags, eventMessageReason, sequenceNumber, |
| timestamp, messageTextString); |
| |
| ASSERT_EQ(result, 0); |
| EXPECT_EQ( |
| messageTextString.data(), |
| std::bit_cast<const char*>(buf.data() + gpu::xidEventMinDataSize)); |
| EXPECT_EQ(messageTextString.size(), message.size()); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetEccErrorCountsRequestSuccess) |
| { |
| const uint8_t instanceId = 1; |
| std::array<uint8_t, gpu::getEccErrorCountsRequestSize> buf{}; |
| |
| int result = gpu::encodeGetEccErrorCountsRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf{std::span<const uint8_t>(buf)}; |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t recvInstanceId = 0; |
| uint8_t recvMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, recvInstanceId, |
| recvMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(recvInstanceId & ocp::accelerator_management::instanceIdBitMask, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(recvMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_ECC_ERROR_COUNTS)); |
| |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetEccErrorCountsRequestBufferTooSmall) |
| { |
| const uint8_t instanceId = 1; |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeGetEccErrorCountsRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Helper: pack a CommonResponse header using PackBuffer |
| // Layout: BindingPciVid(5) + command(1) + cc(1) + reason_code(2) |
| void packCommonResponseHeader(PackBuffer& packer, uint8_t msgType, |
| uint8_t command, uint8_t completionCode, |
| uint16_t reasonCode) |
| { |
| // BindingPciVid header for response |
| // pci_vendor_id (big-endian) |
| packer.pack(static_cast<uint16_t>(htobe16(gpu::nvidiaPciVendorId))); |
| // instance_id: response (bit 7 clear), instance=0 |
| packer.pack(static_cast<uint8_t>(0x00)); |
| // ocp_version: type=8 (upper nibble), version=9 (lower nibble) |
| packer.pack(static_cast<uint8_t>(0x89)); |
| // ocp_accelerator_management_msg_type |
| packer.pack(msgType); |
| |
| packer.pack(command); |
| packer.pack(completionCode); |
| packer.pack(reasonCode); |
| } |
| |
| // Tests for gpu::decodeGetCurrentUtilizationModeResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseSuccess) |
| { |
| // CommonResponse header(9) + data_size(2) + gpuUtil(4) + memUtil(4) = 19 |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| // data_size = 8 (2 x uint32_t) |
| packer.pack(static_cast<uint16_t>(8)); |
| // gpuUtilization |
| packer.pack(static_cast<uint32_t>(75)); |
| // memoryUtilization |
| packer.pack(static_cast<uint32_t>(42)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(gpuUtilization, 75U); |
| EXPECT_EQ(memoryUtilization, 42U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseZeroValues) |
| { |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| packer.pack(static_cast<uint16_t>(8)); |
| packer.pack(static_cast<uint32_t>(0)); |
| packer.pack(static_cast<uint32_t>(0)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(gpuUtilization, 0U); |
| EXPECT_EQ(memoryUtilization, 0U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseMaxValues) |
| { |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| packer.pack(static_cast<uint16_t>(8)); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(gpuUtilization, 0xFFFFFFFFU); |
| EXPECT_EQ(memoryUtilization, 0xFFFFFFFFU); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseError) |
| { |
| // Non-success response: header(9) only, no data payload |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR), |
| 0x1234); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseInvalidDataSize) |
| { |
| // Valid header but wrong data_size (4 instead of 8) |
| std::vector<uint8_t> buf(15); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| // Wrong data_size: 4 instead of expected 8 |
| packer.pack(static_cast<uint16_t>(4)); |
| packer.pack(static_cast<uint32_t>(100)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentUtilizationModeResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(4); // Too small for response header |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, cc, reasonCode, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for the long-running variant: |
| // gpu::decodeGetCurrentUtilizationModeResponse(buf, gpuUtilization, |
| // memoryUtilization) |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetCurrentUtilizationModeLongRunningResponseSuccess) |
| { |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2); |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint32_t>(75)); // gpuUtilization |
| packer.pack(static_cast<uint32_t>(42)); // memoryUtilization |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(gpuUtilization, 75U); |
| EXPECT_EQ(memoryUtilization, 42U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetCurrentUtilizationModeLongRunningResponseZeroValues) |
| { |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2); |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint32_t>(0)); |
| packer.pack(static_cast<uint32_t>(0)); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(gpuUtilization, 0U); |
| EXPECT_EQ(memoryUtilization, 0U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetCurrentUtilizationModeLongRunningResponseMaxValues) |
| { |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2); |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, gpuUtilization, memoryUtilization); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(gpuUtilization, 0xFFFFFFFFU); |
| EXPECT_EQ(memoryUtilization, 0xFFFFFFFFU); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetCurrentUtilizationModeLongRunningResponseBufferTooSmall) |
| { |
| // 7 bytes: enough for gpuUtilization but truncates memoryUtilization |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2 - 1); |
| |
| uint32_t gpuUtilization{}; |
| uint32_t memoryUtilization{}; |
| int result = gpu::decodeGetCurrentUtilizationModeResponse( |
| buf, gpuUtilization, memoryUtilization); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccErrorCountsResponseSuccess) |
| { |
| constexpr uint16_t eccDataSize = sizeof(uint16_t) + sizeof(uint32_t) * 5; |
| std::vector<uint8_t> buf( |
| ocp::accelerator_management::commonResponseSize + eccDataSize); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_ECC_ERROR_COUNTS)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| pbuf.pack(eccDataSize); |
| pbuf.pack(uint16_t{0x0001}); |
| pbuf.pack(uint32_t{100}); |
| pbuf.pack(uint32_t{10}); |
| pbuf.pack(uint32_t{5}); |
| pbuf.pack(uint32_t{50}); |
| pbuf.pack(uint32_t{2}); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t flags{}; |
| uint32_t sramCorrected{}; |
| uint32_t sramUncorrectedSecded{}; |
| uint32_t sramUncorrectedParity{}; |
| uint32_t dramCorrected{}; |
| uint32_t dramUncorrected{}; |
| |
| int result = gpu::decodeGetEccErrorCountsResponse( |
| buf, cc, reasonCode, flags, sramCorrected, sramUncorrectedSecded, |
| sramUncorrectedParity, dramCorrected, dramUncorrected); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(flags, 0x0001); |
| EXPECT_EQ(sramCorrected, 100U); |
| EXPECT_EQ(sramUncorrectedSecded, 10U); |
| EXPECT_EQ(sramUncorrectedParity, 5U); |
| EXPECT_EQ(dramCorrected, 50U); |
| EXPECT_EQ(dramUncorrected, 2U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccErrorCountsResponseError) |
| { |
| std::array<uint8_t, ocp::accelerator_management::commonResponseSize> buf{}; |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_ECC_ERROR_COUNTS)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); |
| pbuf.pack(htole16(uint16_t{0x1234})); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t flags{}; |
| uint32_t sramCorrected{}; |
| uint32_t sramUncorrectedSecded{}; |
| uint32_t sramUncorrectedParity{}; |
| uint32_t dramCorrected{}; |
| uint32_t dramUncorrected{}; |
| |
| int result = gpu::decodeGetEccErrorCountsResponse( |
| buf, cc, reasonCode, flags, sramCorrected, sramUncorrectedSecded, |
| sramUncorrectedParity, dramCorrected, dramUncorrected); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccErrorCountsResponseBufferTooSmall) |
| { |
| std::array<uint8_t, ocp::accelerator_management::commonResponseSize> buf{}; |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_ECC_ERROR_COUNTS)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| pbuf.pack(uint16_t{2}); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint16_t flags{}; |
| uint32_t sramCorrected{}; |
| uint32_t sramUncorrectedSecded{}; |
| uint32_t sramUncorrectedParity{}; |
| uint32_t dramCorrected{}; |
| uint32_t dramUncorrected{}; |
| |
| int result = gpu::decodeGetEccErrorCountsResponse( |
| buf, cc, reasonCode, flags, sramCorrected, sramUncorrectedSecded, |
| sramUncorrectedParity, dramCorrected, dramUncorrected); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentClockFrequencyRequestSuccess) |
| { |
| const uint8_t instanceId = 5; |
| std::array<uint8_t, gpu::getCurrentClockFrequencyRequestSize> buf{}; |
| |
| int result = gpu::encodeGetCurrentClockFrequencyRequest( |
| instanceId, gpu::ClockType::MEMORY_CLOCK, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf{std::span<const uint8_t>(buf)}; |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t recvInstanceId = 0; |
| uint8_t recvMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, recvInstanceId, |
| recvMsgType), |
| 0); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ( |
| command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_CLOCK_FREQUENCY)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| uint8_t clockId = 0; |
| ubuf.unpack(clockId); |
| EXPECT_EQ(clockId, static_cast<uint8_t>(gpu::ClockType::MEMORY_CLOCK)); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetCurrentClockFrequencyRequestBufferTooSmall) |
| { |
| const uint8_t instanceId = 5; |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeGetCurrentClockFrequencyRequest( |
| instanceId, gpu::ClockType::MEMORY_CLOCK, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentClockFrequencyResponseSuccess) |
| { |
| std::vector<uint8_t> buf( |
| ocp::accelerator_management::commonResponseSize + sizeof(uint32_t)); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_CLOCK_FREQUENCY)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| pbuf.pack(htole16(static_cast<uint16_t>(sizeof(uint32_t)))); |
| pbuf.pack(htole32(uint32_t{405})); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t clockFreqMHz{}; |
| |
| int result = gpu::decodeGetCurrentClockFrequencyResponse( |
| buf, cc, reasonCode, clockFreqMHz); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(clockFreqMHz, 405U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentClockFrequencyResponseError) |
| { |
| // CommonNonSuccessResponse: BindingPciVid(5) + command(1) + cc(1) + |
| // reason_code(2) = 9 bytes |
| std::vector<uint8_t> buf(9); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_CLOCK_FREQUENCY)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); |
| pbuf.pack(htole16(uint16_t{0x5678})); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t clockFreqMHz{}; |
| |
| int result = gpu::decodeGetCurrentClockFrequencyResponse( |
| buf, cc, reasonCode, clockFreqMHz); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0x5678); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetCurrentClockFrequencyResponseDataSizeMismatch) |
| { |
| std::vector<uint8_t> buf(ocp::accelerator_management::commonResponseSize); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 5, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CURRENT_CLOCK_FREQUENCY)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| pbuf.pack(htole16(uint16_t{2})); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t clockFreqMHz{}; |
| |
| int result = gpu::decodeGetCurrentClockFrequencyResponse( |
| buf, cc, reasonCode, clockFreqMHz); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for encodeGetClockLimitRequest |
| TEST_F(GpuMctpVdmTests, EncodeGetClockLimitRequestSuccess) |
| { |
| const uint8_t instanceId = 15; |
| std::array<uint8_t, gpu::getClockLimitRequestSize> buf{}; |
| |
| int result = gpu::encodeGetClockLimitRequest( |
| instanceId, gpu::ClockType::GRAPHICS_CLOCK, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CLOCK_LIMIT)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(uint8_t)); |
| uint8_t clockType = 0; |
| ubuf.unpack(clockType); |
| EXPECT_EQ(clockType, static_cast<uint8_t>(gpu::ClockType::GRAPHICS_CLOCK)); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetClockLimitRequestBufferTooSmall) |
| { |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeGetClockLimitRequest( |
| 15, gpu::ClockType::GRAPHICS_CLOCK, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for decodeGetClockLimitResponse |
| TEST_F(GpuMctpVdmTests, DecodeGetClockLimitResponseSuccess) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CLOCK_LIMIT)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(4 * sizeof(uint32_t))); // data_size |
| pbuf.pack(static_cast<uint32_t>(300)); // requestedLimitMin |
| pbuf.pack(static_cast<uint32_t>(2100)); // requestedLimitMax |
| pbuf.pack(static_cast<uint32_t>(500)); // presentLimitMin |
| pbuf.pack(static_cast<uint32_t>(1800)); // presentLimitMax |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t requestedLimitMin{}; |
| uint32_t requestedLimitMax{}; |
| uint32_t presentLimitMin{}; |
| uint32_t presentLimitMax{}; |
| |
| int result = gpu::decodeGetClockLimitResponse( |
| buf, cc, reasonCode, requestedLimitMin, requestedLimitMax, |
| presentLimitMin, presentLimitMax); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(requestedLimitMin, 300U); |
| EXPECT_EQ(requestedLimitMax, 2100U); |
| EXPECT_EQ(presentLimitMin, 500U); |
| EXPECT_EQ(presentLimitMax, 1800U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetClockLimitResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CLOCK_LIMIT)); // cmd |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xBBBB)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t requestedLimitMin{}; |
| uint32_t requestedLimitMax{}; |
| uint32_t presentLimitMin{}; |
| uint32_t presentLimitMax{}; |
| |
| int result = gpu::decodeGetClockLimitResponse( |
| buf, cc, reasonCode, requestedLimitMin, requestedLimitMax, |
| presentLimitMin, presentLimitMax); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xBBBB); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetClockLimitResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(7); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t requestedLimitMin{}; |
| uint32_t requestedLimitMax{}; |
| uint32_t presentLimitMin{}; |
| uint32_t presentLimitMax{}; |
| |
| int result = gpu::decodeGetClockLimitResponse( |
| buf, cc, reasonCode, requestedLimitMin, requestedLimitMax, |
| presentLimitMin, presentLimitMax); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetClockLimitResponseInvalidDataSize) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_CLOCK_LIMIT)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(4)); // data_size (wrong) |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t requestedLimitMin{}; |
| uint32_t requestedLimitMax{}; |
| uint32_t presentLimitMin{}; |
| uint32_t presentLimitMax{}; |
| |
| int result = gpu::decodeGetClockLimitResponse( |
| buf, cc, reasonCode, requestedLimitMin, requestedLimitMax, |
| presentLimitMin, presentLimitMax); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::encodeGetViolationDurationRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetViolationDurationRequestSuccess) |
| { |
| const uint8_t instanceId = 3; |
| std::array<uint8_t, gpu::getViolationDurationRequestSize> buf{}; |
| |
| int result = gpu::encodeGetViolationDurationRequest(instanceId, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf{std::span<const uint8_t>(buf)}; |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t recvInstanceId = 0; |
| uint8_t recvMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, recvInstanceId, |
| recvMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(recvInstanceId & ocp::accelerator_management::instanceIdBitMask, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(recvMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VIOLATION_DURATION)); |
| |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetViolationDurationRequestBufferTooSmall) |
| { |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeGetViolationDurationRequest(0, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeGetViolationDurationResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationResponseSuccess) |
| { |
| constexpr uint16_t violationDataSize = sizeof(uint64_t) * 4; |
| std::vector<uint8_t> buf( |
| ocp::accelerator_management::commonResponseSize + violationDataSize); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VIOLATION_DURATION)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| pbuf.pack(violationDataSize); |
| pbuf.pack(uint64_t{1'000'000'000ULL}); // hwViolation = 1s |
| pbuf.pack(uint64_t{2'000'000'000ULL}); // globalSwViolation = 2s |
| pbuf.pack(uint64_t{3'500'000'000ULL}); // powerViolation = 3.5s |
| pbuf.pack(uint64_t{500'000'000ULL}); // thermalViolation = 0.5s |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, cc, reasonCode, hwViolation, globalSwViolation, powerViolation, |
| thermalViolation); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(hwViolation, 1'000'000'000ULL); |
| EXPECT_EQ(globalSwViolation, 2'000'000'000ULL); |
| EXPECT_EQ(powerViolation, 3'500'000'000ULL); |
| EXPECT_EQ(thermalViolation, 500'000'000ULL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationResponseError) |
| { |
| std::array<uint8_t, ocp::accelerator_management::commonResponseSize> buf{}; |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VIOLATION_DURATION)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_NOT_READY)); |
| pbuf.pack(htole16(uint16_t{0xABCD})); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, cc, reasonCode, hwViolation, globalSwViolation, powerViolation, |
| thermalViolation); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERR_NOT_READY); |
| EXPECT_EQ(reasonCode, 0xABCD); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationResponseInvalidDataSize) |
| { |
| std::vector<uint8_t> buf(ocp::accelerator_management::commonResponseSize + |
| sizeof(uint16_t) + sizeof(uint64_t)); |
| |
| PackBuffer pbuf{std::span<uint8_t>(buf)}; |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 1, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_VIOLATION_DURATION)); |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| pbuf.pack(uint16_t{0}); |
| // Wrong data_size: 8 instead of expected 32 |
| pbuf.pack(static_cast<uint16_t>(sizeof(uint64_t))); |
| pbuf.pack(uint64_t{0}); |
| EXPECT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, cc, reasonCode, hwViolation, globalSwViolation, powerViolation, |
| thermalViolation); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationResponseBufferTooSmall) |
| { |
| std::array<uint8_t, 4> buf{}; // Too small for response header |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, cc, reasonCode, hwViolation, globalSwViolation, powerViolation, |
| thermalViolation); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for the long-running variant: |
| // gpu::decodeGetViolationDurationResponse(buf, hw, sw, power, thermal) |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationLongRunningResponseSuccess) |
| { |
| std::vector<uint8_t> buf(sizeof(uint64_t) * 4); |
| PackBuffer packer(buf); |
| packer.pack(uint64_t{1'000'000'000ULL}); // hw = 1s |
| packer.pack(uint64_t{2'000'000'000ULL}); // globalSw = 2s |
| packer.pack(uint64_t{3'500'000'000ULL}); // power = 3.5s |
| packer.pack(uint64_t{500'000'000ULL}); // thermal = 0.5s |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, hwViolation, globalSwViolation, powerViolation, thermalViolation); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(hwViolation, 1'000'000'000ULL); |
| EXPECT_EQ(globalSwViolation, 2'000'000'000ULL); |
| EXPECT_EQ(powerViolation, 3'500'000'000ULL); |
| EXPECT_EQ(thermalViolation, 500'000'000ULL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetViolationDurationLongRunningResponseZeroValues) |
| { |
| std::vector<uint8_t> buf(sizeof(uint64_t) * 4); |
| PackBuffer packer(buf); |
| packer.pack(uint64_t{0}); |
| packer.pack(uint64_t{0}); |
| packer.pack(uint64_t{0}); |
| packer.pack(uint64_t{0}); |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, hwViolation, globalSwViolation, powerViolation, thermalViolation); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(hwViolation, 0U); |
| EXPECT_EQ(globalSwViolation, 0U); |
| EXPECT_EQ(powerViolation, 0U); |
| EXPECT_EQ(thermalViolation, 0U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetViolationDurationLongRunningResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(sizeof(uint64_t) * 4 - 1); // 31 bytes, too small |
| |
| uint64_t hwViolation{}; |
| uint64_t globalSwViolation{}; |
| uint64_t powerViolation{}; |
| uint64_t thermalViolation{}; |
| |
| int result = gpu::decodeGetViolationDurationResponse( |
| buf, hwViolation, globalSwViolation, powerViolation, thermalViolation); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| // Tests for gpu::encodeGetEccModeRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetEccModeRequestSuccess) |
| { |
| const uint8_t instanceId = 4; |
| std::array<uint8_t, gpu::getEccModeRequestSize> buf{}; |
| |
| int result = gpu::encodeGetEccModeRequest(instanceId, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf{std::span<const uint8_t>(buf)}; |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t recvInstanceId = 0; |
| uint8_t recvMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, recvInstanceId, |
| recvMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(recvInstanceId & ocp::accelerator_management::instanceIdBitMask, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(recvMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_ECC_MODE)); |
| |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetEccModeRequestBufferTooSmall) |
| { |
| std::array<uint8_t, 1> buf{}; |
| int result = gpu::encodeGetEccModeRequest(0, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeGetEccModeResponse |
| |
| namespace |
| { |
| void packEccModeResponse(std::span<uint8_t> buf, uint8_t completionCode, |
| uint8_t flags) |
| { |
| PackBuffer packer(buf); |
| ocp::accelerator_management::packHeader( |
| packer, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 0, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| packer.pack( |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_ECC_MODE)); |
| packer.pack(completionCode); |
| packer.pack(uint16_t{0}); // reasonCode |
| packer.pack(static_cast<uint16_t>(sizeof(flags))); // dataSize |
| packer.pack(flags); |
| } |
| } // namespace |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeResponseBothEnabled) |
| { |
| // header(9) + dataSize(2) + flags(1) = 12 |
| std::vector<uint8_t> buf(12); |
| packEccModeResponse( |
| buf, |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0x03U); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| bool current = false; |
| bool pending = false; |
| |
| int result = |
| gpu::decodeGetEccModeResponse(buf, cc, reasonCode, current, pending); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_TRUE(current); |
| EXPECT_TRUE(pending); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeResponseCurrentOnly) |
| { |
| std::vector<uint8_t> buf(12); |
| packEccModeResponse( |
| buf, |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0x01U); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| bool current = false; |
| bool pending = true; |
| |
| int result = |
| gpu::decodeGetEccModeResponse(buf, cc, reasonCode, current, pending); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_TRUE(current); |
| EXPECT_FALSE(pending); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeResponsePendingOnly) |
| { |
| std::vector<uint8_t> buf(12); |
| packEccModeResponse( |
| buf, |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0x02U); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| bool current = true; |
| bool pending = false; |
| |
| int result = |
| gpu::decodeGetEccModeResponse(buf, cc, reasonCode, current, pending); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_FALSE(current); |
| EXPECT_TRUE(pending); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeResponseInvalidDataSize) |
| { |
| // dataSize advertised as 2 but only 1 byte present after header |
| std::vector<uint8_t> buf(12); |
| PackBuffer packer(buf); |
| ocp::accelerator_management::packHeader( |
| packer, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 0, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| packer.pack( |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands::GET_ECC_MODE)); |
| packer.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); |
| packer.pack(uint16_t{0}); |
| packer.pack(uint16_t{2}); // wrong dataSize |
| packer.pack(uint8_t{0}); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| bool current = false; |
| bool pending = false; |
| |
| int result = |
| gpu::decodeGetEccModeResponse(buf, cc, reasonCode, current, pending); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for the long-running payload overload of |
| // gpu::decodeGetEccModeResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeLongRunningResponseBothEnabled) |
| { |
| std::vector<uint8_t> buf{0x03}; |
| |
| bool current = false; |
| bool pending = false; |
| const int result = gpu::decodeGetEccModeResponse(buf, current, pending); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_TRUE(current); |
| EXPECT_TRUE(pending); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeLongRunningResponseCurrentOnly) |
| { |
| std::vector<uint8_t> buf{0x01}; |
| |
| bool current = false; |
| bool pending = false; |
| const int result = gpu::decodeGetEccModeResponse(buf, current, pending); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_TRUE(current); |
| EXPECT_FALSE(pending); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetEccModeLongRunningResponseEmptyBuffer) |
| { |
| std::vector<uint8_t> buf; |
| |
| bool current = false; |
| bool pending = false; |
| const int result = gpu::decodeGetEccModeResponse(buf, current, pending); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| // Tests for gpu::encodeGetMemoryCapacityUtilizationRequest |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetMemoryCapacityUtilizationRequestSuccess) |
| { |
| const uint8_t instanceId = 4; |
| std::array<uint8_t, ocp::accelerator_management::commonRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeGetMemoryCapacityUtilizationRequest(instanceId, buf); |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf{std::span<const uint8_t>(buf)}; |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t recvInstanceId = 0; |
| uint8_t recvMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, recvInstanceId, |
| recvMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(recvInstanceId & ocp::accelerator_management::instanceIdBitMask, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(recvMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION)); |
| |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetMemoryCapacityUtilizationRequestBufferTooSmall) |
| { |
| std::array<uint8_t, 1> buf{}; |
| int result = gpu::encodeGetMemoryCapacityUtilizationRequest(0, buf); |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for gpu::decodeGetMemoryCapacityUtilizationResponse |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetMemoryCapacityUtilizationResponseSuccess) |
| { |
| // CommonResponse header(9) + data_size(2) + reserved(4) + used(4) = 19 |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| // data_size = 8 (2 x uint32_t) |
| packer.pack(static_cast<uint16_t>(8)); |
| packer.pack(static_cast<uint32_t>(1024)); |
| packer.pack(static_cast<uint32_t>(8192)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, cc, reasonCode, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| EXPECT_EQ(reservedMemory, 1024U); |
| EXPECT_EQ(usedMemory, 8192U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetMemoryCapacityUtilizationResponseZeroValues) |
| { |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| packer.pack(static_cast<uint16_t>(8)); |
| packer.pack(static_cast<uint32_t>(0)); |
| packer.pack(static_cast<uint32_t>(0)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, cc, reasonCode, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reservedMemory, 0U); |
| EXPECT_EQ(usedMemory, 0U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetMemoryCapacityUtilizationResponseMaxValues) |
| { |
| std::vector<uint8_t> buf(19); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| packer.pack(static_cast<uint16_t>(8)); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| packer.pack(static_cast<uint32_t>(0xFFFFFFFF)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, cc, reasonCode, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reservedMemory, 0xFFFFFFFFU); |
| EXPECT_EQ(usedMemory, 0xFFFFFFFFU); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetMemoryCapacityUtilizationResponseError) |
| { |
| // Non-success response: header(9) only, no data payload |
| std::vector<uint8_t> buf(9); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR), |
| 0x1234); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, cc, reasonCode, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetMemoryCapacityUtilizationResponseInvalidDataSize) |
| { |
| // Valid header but wrong data_size (4 instead of 8) |
| std::vector<uint8_t> buf(15); |
| PackBuffer packer(buf); |
| |
| packCommonResponseHeader( |
| packer, static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL), |
| static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_MEMORY_CAPACITY_UTILIZATION), |
| static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS), |
| 0); |
| packer.pack(static_cast<uint16_t>(4)); |
| packer.pack(static_cast<uint32_t>(100)); |
| |
| ASSERT_EQ(packer.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, cc, reasonCode, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for the long-running payload overload of |
| // gpu::decodeGetMemoryCapacityUtilizationResponse |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetMemoryCapacityUtilizationLongRunningResponseSuccess) |
| { |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2); |
| PackBuffer packer(buf); |
| packer.pack(static_cast<uint32_t>(1024)); // reserved |
| packer.pack(static_cast<uint32_t>(4096)); // used |
| ASSERT_EQ(packer.getError(), 0); |
| |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, reservedMemory, usedMemory); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(reservedMemory, 1024U); |
| EXPECT_EQ(usedMemory, 4096U); |
| } |
| |
| TEST_F(GpuMctpVdmTests, |
| DecodeGetMemoryCapacityUtilizationLongRunningResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(sizeof(uint32_t) * 2 - 1); // 7 bytes, too small |
| |
| uint32_t reservedMemory{}; |
| uint32_t usedMemory{}; |
| |
| int result = gpu::decodeGetMemoryCapacityUtilizationResponse( |
| buf, reservedMemory, usedMemory); |
| |
| EXPECT_NE(result, 0); |
| } |
| |
| // Tests for encodeSetClockLimitRequest |
| TEST_F(GpuMctpVdmTests, EncodeSetClockLimitRequestSuccess) |
| { |
| const uint8_t instanceId = 15; |
| const uint32_t limitMinMHz = 300; |
| const uint32_t limitMaxMHz = 2100; |
| std::array<uint8_t, gpu::setClockLimitRequestSize> buf{}; |
| |
| int result = gpu::encodeSetClockLimitRequest( |
| instanceId, gpu::ClockType::GRAPHICS_CLOCK, |
| gpu::ClockLimitFlag::PERSISTENCE, limitMinMHz, limitMaxMHz, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_CLOCK_LIMIT)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t) + |
| sizeof(uint32_t)); |
| uint8_t clockType = 0; |
| ubuf.unpack(clockType); |
| EXPECT_EQ(clockType, static_cast<uint8_t>(gpu::ClockType::GRAPHICS_CLOCK)); |
| uint8_t flag = 0; |
| ubuf.unpack(flag); |
| EXPECT_EQ(flag, static_cast<uint8_t>(gpu::ClockLimitFlag::PERSISTENCE)); |
| uint32_t unpackedMin = 0; |
| uint32_t unpackedMax = 0; |
| ubuf.unpack(unpackedMin); |
| ubuf.unpack(unpackedMax); |
| EXPECT_EQ(unpackedMin, limitMinMHz); |
| EXPECT_EQ(unpackedMax, limitMaxMHz); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetClockLimitRequestClearFlag) |
| { |
| std::array<uint8_t, gpu::setClockLimitRequestSize> buf{}; |
| |
| int result = |
| gpu::encodeSetClockLimitRequest(7, gpu::ClockType::GRAPHICS_CLOCK, |
| gpu::ClockLimitFlag::CLEAR, 0, 0, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType); |
| uint8_t command = 0; |
| uint8_t dataSize = 0; |
| uint8_t clockType = 0; |
| uint8_t flag = 0; |
| ubuf.unpack(command); |
| ubuf.unpack(dataSize); |
| ubuf.unpack(clockType); |
| ubuf.unpack(flag); |
| EXPECT_EQ(flag, static_cast<uint8_t>(gpu::ClockLimitFlag::CLEAR)); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeSetClockLimitRequestBufferTooSmall) |
| { |
| std::array<uint8_t, 1> buf{}; |
| |
| int result = gpu::encodeSetClockLimitRequest( |
| 15, gpu::ClockType::GRAPHICS_CLOCK, gpu::ClockLimitFlag::PERSISTENCE, |
| 300, 2100, buf); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| // Tests for decodeSetClockLimitResponse |
| TEST_F(GpuMctpVdmTests, DecodeSetClockLimitResponseSuccess) |
| { |
| std::vector<uint8_t> buf(32); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_CLOCK_LIMIT)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(0)); // data_size |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetClockLimitResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetClockLimitResponseError) |
| { |
| std::vector<uint8_t> buf(32); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::SET_CLOCK_LIMIT)); // cmd |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERR_INVALID_DATA)); // CC |
| pbuf.pack(static_cast<uint16_t>(0xAAAA)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetClockLimitResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, |
| ocp::accelerator_management::CompletionCode::ERR_INVALID_DATA); |
| EXPECT_EQ(reasonCode, 0xAAAA); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeSetClockLimitResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(7); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 15, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| |
| int result = gpu::decodeSetClockLimitResponse(buf, cc, reasonCode); |
| |
| EXPECT_EQ(result, EINVAL); |
| } |
| |
| TEST_F(GpuMctpVdmTests, EncodeGetLeakDetectionInfoRequestSuccess) |
| { |
| const uint8_t instanceId = 8; |
| std::vector<uint8_t> buf(256); |
| |
| int result = gpu::encodeGetLeakDetectionInfoRequest(instanceId, buf); |
| |
| EXPECT_EQ(result, 0); |
| |
| UnpackBuffer ubuf(std::span<const uint8_t>(buf.data(), buf.size())); |
| ocp::accelerator_management::MessageType msgType{}; |
| uint8_t unpackedInstanceId = 0; |
| uint8_t unpackedMsgType = 0; |
| EXPECT_EQ(ocp::accelerator_management::unpackHeader( |
| ubuf, gpu::nvidiaPciVendorId, msgType, unpackedInstanceId, |
| unpackedMsgType), |
| 0); |
| EXPECT_EQ(msgType, ocp::accelerator_management::MessageType::REQUEST); |
| EXPECT_EQ(unpackedInstanceId, |
| instanceId & ocp::accelerator_management::instanceIdBitMask); |
| EXPECT_EQ(unpackedMsgType, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| uint8_t command = 0; |
| ubuf.unpack(command); |
| EXPECT_EQ(command, |
| static_cast<uint8_t>( |
| gpu::PlatformEnvironmentalCommands::GET_LEAK_DETECTION_INFO)); |
| uint8_t dataSize = 0; |
| ubuf.unpack(dataSize); |
| EXPECT_EQ(dataSize, 0); |
| EXPECT_EQ(ubuf.getError(), 0); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetLeakDetectionInfoResponseSuccess) |
| { |
| std::vector<uint8_t> buf(128); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_LEAK_DETECTION_INFO)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| |
| // data_size = num_sensors (1) + num_threshold_levels (1) + |
| // (sensor_id (1) + leak_state (1) + thresholds (2 * 2) + |
| // adc_reading (2)) * 1 = 1 + 1 + 8 = 10 |
| pbuf.pack(static_cast<uint16_t>(10)); // data_size |
| pbuf.pack(static_cast<uint8_t>(1)); // numSensors |
| pbuf.pack(static_cast<uint8_t>(2)); // numThresholdLevels |
| |
| // Sensor 1 |
| pbuf.pack(static_cast<uint8_t>(42)); // sensorId |
| pbuf.pack(static_cast<uint8_t>(1)); // leakState |
| pbuf.pack(static_cast<uint16_t>(1000)); // threshold 0 |
| pbuf.pack(static_cast<uint16_t>(2000)); // threshold 1 |
| pbuf.pack(static_cast<uint16_t>(1500)); // adcReadingMv |
| |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<gpu::LeakSensorData> parsedSensors; |
| |
| int result = gpu::decodeGetLeakDetectionInfoResponse(buf, cc, reasonCode, |
| parsedSensors); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::SUCCESS); |
| EXPECT_EQ(reasonCode, 0); |
| ASSERT_EQ(parsedSensors.size(), 1); |
| EXPECT_EQ(parsedSensors[0].sensorId, 42); |
| EXPECT_EQ(parsedSensors[0].leakState, 1); |
| ASSERT_EQ(parsedSensors[0].thresholds.size(), 2); |
| EXPECT_EQ(parsedSensors[0].thresholds[0], 1000); |
| EXPECT_EQ(parsedSensors[0].thresholds[1], 2000); |
| EXPECT_EQ(parsedSensors[0].adcReadingMv, 1500); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetLeakDetectionInfoResponseError) |
| { |
| std::vector<uint8_t> buf(64); |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_LEAK_DETECTION_INFO)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::ERROR)); // CC |
| pbuf.pack(static_cast<uint16_t>(0x1234)); // reason_code |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<gpu::LeakSensorData> parsedSensors; |
| |
| int result = gpu::decodeGetLeakDetectionInfoResponse(buf, cc, reasonCode, |
| parsedSensors); |
| |
| EXPECT_EQ(result, 0); |
| EXPECT_EQ(cc, ocp::accelerator_management::CompletionCode::ERROR); |
| EXPECT_EQ(reasonCode, 0x1234); |
| EXPECT_TRUE(parsedSensors.empty()); |
| } |
| |
| TEST_F(GpuMctpVdmTests, DecodeGetLeakDetectionInfoResponseBufferTooSmall) |
| { |
| std::vector<uint8_t> buf(11); // Enough for header, but not payload |
| PackBuffer pbuf(buf); |
| ocp::accelerator_management::packHeader( |
| pbuf, gpu::nvidiaPciVendorId, |
| ocp::accelerator_management::MessageType::RESPONSE, 3, |
| static_cast<uint8_t>(gpu::MessageType::PLATFORM_ENVIRONMENTAL)); |
| pbuf.pack(static_cast<uint8_t>(gpu::PlatformEnvironmentalCommands:: |
| GET_LEAK_DETECTION_INFO)); // command |
| pbuf.pack(static_cast<uint8_t>( |
| ocp::accelerator_management::CompletionCode::SUCCESS)); // CC |
| pbuf.pack(static_cast<uint16_t>(0)); // reserved |
| pbuf.pack(static_cast<uint16_t>(10)); // data_size |
| |
| ASSERT_EQ(pbuf.getError(), 0); |
| |
| ocp::accelerator_management::CompletionCode cc{}; |
| uint16_t reasonCode{}; |
| std::vector<gpu::LeakSensorData> parsedSensors; |
| |
| int result = gpu::decodeGetLeakDetectionInfoResponse(buf, cc, reasonCode, |
| parsedSensors); |
| |
| EXPECT_NE(result, 0); // Expect failure due to missing data |
| } |
| |
| } // namespace gpu_mctp_tests |