| // Copyright 2024 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "hoth_skmhss_unittest.hpp" |
| |
| #include <blobs-ipmid/blobs.hpp> |
| #include <ipmid/handler.hpp> |
| |
| #include <cstdint> |
| #include <string_view> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| namespace ipmi_hoth |
| { |
| |
| using ::testing::_; |
| using ::testing::ContainerEq; |
| using ::testing::ElementsAre; |
| using ::testing::IsEmpty; |
| using ::testing::Return; |
| |
| class HothSKMHSSReadTest : public HothSKMHSSBasicTest |
| { |
| protected: |
| const uint32_t testOffset = 0; |
| const std::vector<uint8_t> testData = [] { |
| std::vector<uint8_t> ret; |
| for (uint8_t i = 0; i < 64; ++i) |
| ret.push_back(i); |
| return ret; |
| }(); |
| |
| void openUninitializedBlob(int idx) |
| { |
| // Any valid blobs have uninitialized buffer. |
| hvn = createHandlerWithEmptyCache(); |
| |
| EXPECT_CALL(dbus, pingHothd(std::string_view(""))) |
| .WillOnce(Return(true)); |
| fu2::unique_function<void()> cb; |
| testing::StrictMock<MockCancel> cancel; |
| expectRead(idx, cb, cancel, testData); |
| EXPECT_TRUE( |
| hvn->open(session, blobs::OpenFlags::read, legacyPath[idx])); |
| cb(); |
| } |
| }; |
| |
| TEST_F(HothSKMHSSReadTest, InvalidSessionReadIsRejected) |
| { |
| // Verify that read checks for a valid session, returns empty buffer for |
| // failed check. |
| |
| openUninitializedBlob(0); |
| uint16_t wrongSession = session + 1; |
| EXPECT_THROW(hvn->read(wrongSession, testOffset, testData.size()), |
| ipmi::HandlerCompletion); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadOpenBlobWithoutReadFlagReturnsError) |
| { |
| // Verify that read checks for a valid state with open_read flag set. |
| |
| EXPECT_CALL(dbus, pingHothd(std::string_view(""))).WillOnce(Return(true)); |
| EXPECT_TRUE(hvn->open(session, 0, legacyPath[1])); |
| EXPECT_THROW(hvn->read(session, testOffset, testData.size()), |
| ipmi::HandlerCompletion); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadOffsetBeyondBufferSizeReturnsEmpty) |
| { |
| // Verify that read with offset beyond buffer size returns empty buffer. |
| |
| openUninitializedBlob(2); |
| uint32_t offsetBeyondBuffer = testData.size(); |
| EXPECT_THAT(hvn->read(session, offsetBeyondBuffer, testData.size()), |
| IsEmpty()); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadFullWrittenData) |
| { |
| // Verify that the read successfully reads back the written data. |
| |
| openUninitializedBlob(3); |
| EXPECT_THAT(hvn->read(session, testOffset, testData.size()), |
| ContainerEq(testData)); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadWrittenDataAtOffset) |
| { |
| // Verify that the read with offset returns the expected data. |
| |
| openUninitializedBlob(0); |
| EXPECT_THAT(hvn->read(session, testOffset, testData.size()), |
| ContainerEq(testData)); |
| |
| // Try reading the written data byte by byte at each offset |
| for (size_t i = 0; i < testData.size(); ++i) |
| { |
| EXPECT_THAT(hvn->read(session, i, 1), ElementsAre(testData[i])); |
| } |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadFullWrittenDataWithBiggerRequestedSize) |
| { |
| // Verify that read with requested size bigger than the written data will |
| // return a response buffer up to the end of the written buffer. |
| |
| openUninitializedBlob(0); |
| uint32_t requestedSizeBeyondBuffer = testData.size() + 1; |
| EXPECT_THAT(hvn->read(session, testOffset, requestedSizeBeyondBuffer), |
| ContainerEq(testData)); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadWrittenDataAtOffsetWithBiggerRequestedSize) |
| { |
| // Verify that read with requested size bigger than the written data at an |
| // offset will return a response buffer up to the end of the written buffer. |
| |
| openUninitializedBlob(1); |
| uint32_t newOffset = testData.size() / 2; |
| uint32_t requestedSizeBeyondBuffer = testData.size() + 1; |
| std::vector<uint8_t> expectedData = |
| std::vector<uint8_t>(testData.begin() + newOffset, testData.end()); |
| |
| EXPECT_THAT(hvn->read(session, newOffset, requestedSizeBeyondBuffer), |
| ContainerEq(expectedData)); |
| } |
| |
| TEST_F(HothSKMHSSReadTest, ReadFullWrittenDataBeyondMaxBufferSize) |
| { |
| // Verify that read with requested size bigger than the maximum buffer size |
| // will return a response buffer up to the end of the written buffer. |
| |
| openUninitializedBlob(2); |
| uint32_t requestedSize = hvn->maxBufferSize() + 1; |
| EXPECT_THAT(hvn->read(session, testOffset, requestedSize), |
| ContainerEq(testData)); |
| } |
| |
| } // namespace ipmi_hoth |