blob: c47eef959bf83b88e73d4e362d333618290a5a18 [file] [log] [blame]
// 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