| // 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 |