blob: a2aa971551f52c96046a2f3c06a3b6899026a699 [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 <cstdint>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include <gtest/gtest.h>
using ::testing::_;
using ::testing::ContainerEq;
using ::testing::Return;
using ::testing::UnorderedElementsAreArray;
namespace ipmi_hoth
{
class HothSKMHSSCommitTest : public HothSKMHSSBasicTest
{
protected:
void openAndWriteRandomHss(int idx)
{
std::vector<uint8_t> data(64);
std::srand(1);
std::generate(data.begin(), data.end(), std::rand);
EXPECT_CALL(dbus, pingHothd(std::string_view("")))
.WillOnce(Return(true));
fu2::unique_function<void()> cb;
testing::StrictMock<MockCancel> cancel;
expectRead(idx, cb, cancel, data);
EXPECT_TRUE(
hvn->open(session, blobs::OpenFlags::read | blobs::OpenFlags::write,
legacyPath[idx]));
cb();
}
};
TEST_F(HothSKMHSSCommitTest, InvalidSessionCommitIsRejected)
{
// Verify the hoth command handler checks for a valid session.
EXPECT_FALSE(hvn->commit(session, std::vector<uint8_t>()));
}
TEST_F(HothSKMHSSCommitTest, CommitWithUnexpectedDataParamReturnsFalse)
{
openAndWriteRandomHss(0);
EXPECT_FALSE(hvn->commit(session, std::vector<uint8_t>({1, 2, 3})));
}
TEST_F(HothSKMHSSCommitTest, MultiCommit)
{
openAndWriteRandomHss(1);
// No change does nothing
EXPECT_TRUE(hvn->commit(session, {}));
EXPECT_TRUE(hvn->write(session, 0, {0}));
// Test an error case
EXPECT_CALL(hvnutil, writeSKMHSS(1, _))
.WillOnce(Return(std::vector<uint8_t>{11}));
fu2::unique_function<void()> cb;
testing::StrictMock<MockCancel> cancel;
expectCmd(/*slot=*/1, cb, cancel, /*data=*/{});
EXPECT_TRUE(hvn->commit(session, {}));
blobs::BlobMeta meta;
EXPECT_TRUE(hvn->stat(session, &meta));
EXPECT_EQ(blobs::StateFlags::committing | blobs::StateFlags::open_write |
blobs::StateFlags::open_read,
meta.blobState);
cb();
EXPECT_TRUE(hvn->stat(session, &meta));
EXPECT_EQ(blobs::StateFlags::commit_error | blobs::StateFlags::open_write |
blobs::StateFlags::open_read,
meta.blobState);
// Test repeat commit translates into success
EXPECT_CALL(hvnutil, writeSKMHSS(1, _))
.WillOnce(Return(std::vector<uint8_t>{11}));
std::array<uint8_t, 1> arr;
expectCmd(/*slot=*/1, cb, cancel,
/*data=*/std::span<uint8_t>(arr).subspan(0, 0));
EXPECT_TRUE(hvn->commit(session, {}));
EXPECT_TRUE(hvn->stat(session, &meta));
EXPECT_EQ(blobs::StateFlags::committing | blobs::StateFlags::open_write |
blobs::StateFlags::open_read,
meta.blobState);
cb();
EXPECT_TRUE(hvn->stat(session, &meta));
EXPECT_EQ(blobs::StateFlags::committed | blobs::StateFlags::open_write |
blobs::StateFlags::open_read,
meta.blobState);
// No change does nothing
EXPECT_TRUE(hvn->commit(session, {}));
}
} // namespace ipmi_hoth