blob: 253f8ca184303199e578776dfcaa5321ca5f5afb [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_updater_cli.hpp"
#include <stdio.h>
#include <filesystem>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace google::hoth::tools
{
namespace
{
using ::testing::_;
using ::testing::Return;
class HothUpdaterCLIMock : public HothUpdaterCLI
{
public:
MOCK_METHOD(HothVersionStringsRsp, getHothVersion,
(sdbusplus::bus::bus & bus, std::string_view hoth_id));
MOCK_METHOD(HothActivationStatistics, getHothActivationStatistics,
(sdbusplus::bus::bus & bus, std::string_view hoth_id));
MOCK_METHOD(void, spiWrite,
(sdbusplus::bus::bus&, std::string_view,
const std::span<const uint8_t>, std::optional<uint32_t>));
MOCK_METHOD(std::vector<uint8_t>, readFileIntoByteArray,
(std::string_view));
MOCK_METHOD(FirmwareUpdateStatus, getFirmwareUpdateStatus,
(sdbusplus::bus::bus & bus, std::string_view hoth_id));
};
TEST(PayloadUpdateCLITest, splitStringTest)
{
std::vector<std::string> sp = splitString("", ',');
EXPECT_EQ(sp.size(), 0);
sp = splitString("product_3_1", ',');
EXPECT_EQ(sp.size(), 1);
EXPECT_EQ(sp[0], "product_3_1");
sp = splitString("product_3_1,product_3_2", ',');
EXPECT_EQ(sp.size(), 2);
EXPECT_EQ(sp[0], "product_3_1");
EXPECT_EQ(sp[1], "product_3_2");
}
class HothUpdaterCLITest : public ::testing::Test
{
protected:
HothUpdaterCLIMock cli;
};
// Test for making sure doActivationCheck does not error out
TEST_F(HothUpdaterCLITest, doActivationCheckTest)
{
HothVersionStringsRsp rsp = {.header =
{
.struct_version = 0,
.checksum = 0,
.result = 0,
.data_len = 0,
.reserved = 0,
},
.version = {
.version_string_ro = "1.2.345",
.version_string_rw = "2.3.456",
.reserved = "",
.current_image = 0,
}};
Args args;
args.expectedRwVersion = "2.3.456";
EXPECT_CALL(cli, getHothVersion(_, _)).Times(1).WillOnce(Return(rsp));
EXPECT_CALL(cli, getHothActivationStatistics(_, _)).Times(0);
cli.doActivationCheck(args);
}
// Test doActivationCheck when version mismatch.
TEST_F(HothUpdaterCLITest, doActivationCheckWrongVersion)
{
HothVersionStringsRsp rsp = {.header =
{
.struct_version = 0,
.checksum = 0,
.result = 0,
.data_len = 0,
.reserved = 0,
},
.version = {
.version_string_ro = "1.2.345",
.version_string_rw = "2.3.456",
.reserved = "",
.current_image = 0,
}};
HothActivationStatistics stats = {
.rw_failure_code = 1,
.rw_failed_minor = 2,
.ro_failure_code = 0xffff,
.reset_flags = 3,
.uptime_us = 0xdeadbeeffeedbead,
};
Args args;
args.expectedRwVersion = "3.4.567";
EXPECT_CALL(cli, getHothVersion(_, _)).Times(1).WillOnce(Return(rsp));
EXPECT_CALL(cli, getHothActivationStatistics(_, _))
.Times(1)
.WillOnce(Return(stats));
EXPECT_THROW(cli.doActivationCheck(args), std::runtime_error);
}
// Test for making sure the doUpdate loop works correctly
TEST_F(HothUpdaterCLITest, getFirmwareUpdateStatusTest)
{
Args args;
args.updateMethod = "spi";
args.imageFilename = "dummy";
std::vector<uint8_t> dummy_image = {0, 1, 2, 3};
EXPECT_CALL(cli, readFileIntoByteArray(_))
.Times(1)
.WillOnce(Return(dummy_image));
EXPECT_CALL(cli, spiWrite(_, _, _, _)).Times(1);
EXPECT_CALL(cli, getFirmwareUpdateStatus(_, _))
.Times(3)
.WillOnce(Return(FirmwareUpdateStatus::InProgress))
.WillOnce(Return(FirmwareUpdateStatus::InProgress))
.WillOnce(Return(FirmwareUpdateStatus::Done));
cli.doUpdate(args);
}
} // namespace
} // namespace google::hoth::tools