// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The calling structure of HammerUpdater:
//   Run() => RunLoop() => RunOnce() => PostRWProcess().
// Since RunLoop only iterately call the Run() method, so we don't test it
// directly. Therefore, we have 3-layer unittests:
//
// - HammerUpdaterFlowTest:
//  - Test the logic of Run(), the interaction with RunOnce().
//  - Mock RunOnce() and data members.
//
// - HammerUpdaterRWTest:
//  - Test the logic of RunOnce(), the interaction with PostRWProcess() and
//    external interfaces (fw_updater, pair_manager, ...etc).
//  - One exception: Test a special sequence that needs to reset 3 times called
//    by Run().
//  - Mock PostRWProcess() and data members.
//
// - HammerUpdaterPostRWTest:
//  - Test the individual methods called from within PostRWProcess(),
//    like Pair, UpdateRO, RunTouchpadUpdater().
//  - Test logic for RunTouchpadUpdater():
//    - Verify the return value if we can't get touchpad infomation.
//    - Verify the IC size matches with local firmware binary blob.
//    - Verify the entire firmware blob hash matches one accepted in RW EC.
//    - Verify the return value if update is failed during process.
//  - Mock all external data members only.

#include <memory>
#include <utility>

#include <base/logging.h>
#include <base/files/file_path.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library.h>
#include <metrics/metrics_library_mock.h>

#include "hammerd/hammer_updater.h"
#include "hammerd/mock_dbus_wrapper.h"
#include "hammerd/mock_pair_utils.h"
#include "hammerd/mock_update_fw.h"
#include "hammerd/uma_metric_names.h"
#include "hammerd/update_fw.h"

using testing::_;
using testing::AnyNumber;
using testing::Assign;
using testing::AtLeast;
using testing::DoAll;
using testing::Exactly;
using testing::InSequence;
using testing::Return;
using testing::ReturnPointee;

namespace hammerd {

ACTION_P(Increment, n) {
  ++(*n);
}
ACTION_P(Decrement, n) {
  --(*n);
}

class MockRunOnceHammerUpdater : public HammerUpdater {
 public:
  using HammerUpdater::HammerUpdater;
  ~MockRunOnceHammerUpdater() override = default;

  MOCK_METHOD(RunStatus, RunOnce, (), (override));
};

class MockRWProcessHammerUpdater : public HammerUpdater {
 public:
  using HammerUpdater::HammerUpdater;
  ~MockRWProcessHammerUpdater() override = default;

  MOCK_METHOD(RunStatus, PostRWProcess, (), (override));
};

class MockNothing : public HammerUpdater {
 public:
  using HammerUpdater::HammerUpdater;
  ~MockNothing() override = default;
};

template <typename HammerUpdaterType>
class HammerUpdaterTest : public testing::Test {
 public:
  void SetUp() override {
    // Mock out data members.
    hammer_updater_.reset(new HammerUpdaterType{
        ec_image_, touchpad_image_, touchpad_product_id_, touchpad_fw_ver_,
        false, HammerUpdater::ToUpdateCondition("mismatch"),
        std::make_unique<MockFirmwareUpdater>(),
        std::make_unique<MockPairManagerInterface>(),
        std::make_unique<MockDBusWrapper>(),
        std::make_unique<MetricsLibraryMock>()});
    fw_updater_ =
        static_cast<MockFirmwareUpdater*>(hammer_updater_->fw_updater_.get());
    pair_manager_ = static_cast<MockPairManagerInterface*>(
        hammer_updater_->pair_manager_.get());
    dbus_wrapper_ =
        static_cast<MockDBusWrapper*>(hammer_updater_->dbus_wrapper_.get());
    metrics_ =
        static_cast<MetricsLibraryMock*>(hammer_updater_->metrics_.get());
    task_ = &(hammer_updater_->task_);
    update_condition_ = const_cast<HammerUpdater::UpdateCondition*>(
        &(hammer_updater_->update_condition_));
    at_boot_ = const_cast<bool*>(&(hammer_updater_->at_boot_));
    // By default, expect no USB connections to be made. This can
    // be overridden by a call to ExpectUsbConnections.
    usb_connection_count_ = 0;
    EXPECT_CALL(*fw_updater_, TryConnectUsb()).Times(0);
    EXPECT_CALL(*fw_updater_, CloseUsb()).Times(0);

    // These two methods are called at the beginning of each round but not
    // related to most of testing logic. Set the default action here.
    ON_CALL(*fw_updater_, SendFirstPdu()).WillByDefault(Return(true));
    ON_CALL(*fw_updater_, SendDone()).WillByDefault(Return());

    // Do not verify these non-state-changing methods are called.
    ON_CALL(*fw_updater_, LoadEcImage(_)).WillByDefault(Return(true));
    ON_CALL(*fw_updater_, LoadTouchpadImage(_)).WillByDefault(Return(true));
    ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(false));
    ON_CALL(*fw_updater_, IsSectionLocked(_)).WillByDefault(Return(false));
    ON_CALL(*fw_updater_, ValidKey()).WillByDefault(Return(true));
    ON_CALL(*fw_updater_, CurrentSection())
        .WillByDefault(ReturnPointee(&current_section_));
    ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(0));
  }

  void TearDown() override { ASSERT_EQ(usb_connection_count_, 0); }

  void ExpectUsbConnections(const testing::Cardinality count) {
    // Checked in TearDown.
    EXPECT_CALL(*fw_updater_, TryConnectUsb())
        .Times(count)
        .WillRepeatedly(DoAll(Increment(&usb_connection_count_),
                              Return(UsbConnectStatus::kSuccess)));
    EXPECT_CALL(*fw_updater_, CloseUsb())
        .Times(count)
        .WillRepeatedly(DoAll(Decrement(&usb_connection_count_), Return()));
  }

 protected:
  std::unique_ptr<HammerUpdaterType> hammer_updater_;
  MockFirmwareUpdater* fw_updater_;
  MockPairManagerInterface* pair_manager_;
  MockDBusWrapper* dbus_wrapper_;
  MetricsLibraryMock* metrics_;
  std::string ec_image_ = "MOCK EC IMAGE";
  std::string touchpad_image_ = "MOCK TOUCHPAD IMAGE";
  std::string touchpad_product_id_ = "1.0";
  std::string touchpad_fw_ver_ = "2.0";
  int usb_connection_count_;
  HammerUpdater::TaskState* task_;
  HammerUpdater::UpdateCondition* update_condition_;
  bool* at_boot_;
  SectionName current_section_ = SectionName::RO;
};

// We mock RunOnce function here to verify the interaction between Run() and
// RunOnce().
class HammerUpdaterFlowTest
    : public HammerUpdaterTest<MockRunOnceHammerUpdater> {};
// We mock PostRWProcess function here to verify the flow of RW section
// updating.
class HammerUpdaterRWTest
    : public HammerUpdaterTest<MockRWProcessHammerUpdater> {};
// Mock nothing to test the individual methods called from within PostRWProcess.
class HammerUpdaterPostRWTest : public HammerUpdaterTest<MockNothing> {
 public:
  void SetUp() override {
    HammerUpdaterTest::SetUp();
    // Create a nice response of kTouchpadInfo for important fields.
    response_.status = 0x00;
    response_.vendor = ELAN_VENDOR_ID;
    response_.elan.id = 0x01;
    response_.elan.fw_version = 0x02;
    response_.fw_size = touchpad_image_.size();
    std::memcpy(
        response_.allowed_fw_hash,
        SHA256(reinterpret_cast<const uint8_t*>(touchpad_image_.data()),
               response_.fw_size, reinterpret_cast<unsigned char*>(&digest_)),
        SHA256_DIGEST_LENGTH);
  }

 protected:
  TouchpadInfo response_;
  uint8_t digest_[SHA256_DIGEST_LENGTH];
};

// Failed to load EC image.
TEST_F(HammerUpdaterFlowTest, Run_LoadEcImageFailed) {
  ON_CALL(*fw_updater_, LoadEcImage(_)).WillByDefault(Return(false));
  EXPECT_CALL(*fw_updater_, TryConnectUsb()).Times(0);
  EXPECT_CALL(*hammer_updater_, RunOnce()).Times(0);

  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kInvalidFirmware);
}

// Sends reset command if RunOnce returns kNeedReset.
TEST_F(HammerUpdaterFlowTest, Run_AlwaysReset) {
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(HammerUpdater::RunStatus::kNeedReset));
  EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kImmediateReset))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(),
            HammerUpdater::RunStatus::kNeedReset);  // FAILURE
}

// A fatal error occurred during update.
TEST_F(HammerUpdaterFlowTest, Run_FatalError) {
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .WillOnce(Return(HammerUpdater::RunStatus::kFatalError));
  EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kImmediateReset))
      .WillOnce(Return(true));

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(),
            HammerUpdater::RunStatus::kNeedReset);  // FAILURE
}

// After three attempts, Run reports no update needed.
TEST_F(HammerUpdaterFlowTest, Run_Reset3Times) {
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .WillOnce(Return(HammerUpdater::RunStatus::kNeedReset))
      .WillOnce(Return(HammerUpdater::RunStatus::kNeedReset))
      .WillOnce(Return(HammerUpdater::RunStatus::kNeedReset))
      .WillRepeatedly(Return(HammerUpdater::RunStatus::kNoUpdate));
  EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kImmediateReset))
      .Times(3)
      .WillRepeatedly(Return(true));

  ExpectUsbConnections(Exactly(4));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Fails if the base connected is invalid.
// kInvalidBaseConnectedSignal DBus signal should be raised.
TEST_F(HammerUpdaterFlowTest, RunOnce_InvalidDevice) {
  EXPECT_CALL(*fw_updater_, TryConnectUsb())
      .WillRepeatedly(Return(UsbConnectStatus::kInvalidDevice));
  EXPECT_CALL(*fw_updater_, CloseUsb()).WillRepeatedly(Return());

  EXPECT_CALL(*dbus_wrapper_, SendSignal(kInvalidBaseConnectedSignal));

  // Do not call ExpectUsbConnections since it conflicts with our EXPECT_CALLs.
  ASSERT_EQ(hammer_updater_->Run(),
            HammerUpdater::RunStatus::kNeedJump);  // FAILURE
}

// Check PendingRWUpdate metric:
// CommunicationError
TEST_F(HammerUpdaterFlowTest, RunOnce_PendingRWUpdate_CommunicationError) {
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  EXPECT_CALL(*fw_updater_, TryConnectUsb())
      .WillRepeatedly(Return(UsbConnectStatus::kInvalidDevice));
  EXPECT_CALL(*fw_updater_, CloseUsb()).WillRepeatedly(Return());
  EXPECT_CALL(
      *metrics_,
      SendEnumToUMA(kMetricPendingRWUpdate,
                    static_cast<int>(PendingRWUpdate::kCommunicationError),
                    static_cast<int>(PendingRWUpdate::kCount)));

  ASSERT_EQ(hammer_updater_->Run(),
            HammerUpdater::RunStatus::kNeedJump);  // FAILURE
}

// Check PendingRWUpdate metric:
// NoUpdate
TEST_F(HammerUpdaterFlowTest, RunOnce_PendingRWUpdate_NoUpdate) {
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .WillRepeatedly(Return(HammerUpdater::RunStatus::kNoUpdate));
  ON_CALL(*fw_updater_, IsCritical()).WillByDefault(Return(false));
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(false));
  EXPECT_CALL(*metrics_,
              SendEnumToUMA(kMetricPendingRWUpdate,
                            static_cast<int>(PendingRWUpdate::kNoUpdate),
                            static_cast<int>(PendingRWUpdate::kCount)));

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Check PendingRWUpdate metric:
// CriticalUpdate
TEST_F(HammerUpdaterFlowTest, RunOnce_PendingRWUpdate_CriticalUpdate) {
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .WillRepeatedly(Return(HammerUpdater::RunStatus::kNoUpdate));
  ON_CALL(*fw_updater_, IsCritical()).WillByDefault(Return(true));
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(true));
  EXPECT_CALL(*metrics_,
              SendEnumToUMA(kMetricPendingRWUpdate,
                            static_cast<int>(PendingRWUpdate::kCriticalUpdate),
                            static_cast<int>(PendingRWUpdate::kCount)));

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Check PendingRWUpdatemetric:
// NonCriticalUpdate
TEST_F(HammerUpdaterFlowTest, RunOnce_PendingRWUpdate_NonCriticalUpdate) {
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  EXPECT_CALL(*hammer_updater_, RunOnce())
      .WillRepeatedly(Return(HammerUpdater::RunStatus::kNoUpdate));
  ON_CALL(*fw_updater_, IsCritical()).WillByDefault(Return(false));
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(true));
  EXPECT_CALL(
      *metrics_,
      SendEnumToUMA(kMetricPendingRWUpdate,
                    static_cast<int>(PendingRWUpdate::kNonCriticalUpdate),
                    static_cast<int>(PendingRWUpdate::kCount)));

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// In "never" update condition, send DBus signal only if a critical update
// is available.
// Condition:
//   1. Update condition is "never".
//   2. In RW section.
//   3. RW needs a critical update.
TEST_F(HammerUpdaterRWTest, Run_NeverUpdateCriticalUpdate) {
  current_section_ = SectionName::RW;
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(true));
  ON_CALL(*fw_updater_, IsCritical()).WillByDefault(Return(true));

  {
    InSequence dummy;

    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareNeedUpdateSignal));
    EXPECT_CALL(*hammer_updater_, PostRWProcess())
        .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));
  }
  EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW)).Times(0);

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// In "mismatch" update condition, no update is performed.
// Condition:
//   1. Update condition is "mismatch".
//   2. In RW section.
//   3. RW needs update.
TEST_F(HammerUpdaterRWTest, Run_MismatchUpdateRWMismatch) {
  current_section_ = SectionName::RW;
  *update_condition_ = HammerUpdater::UpdateCondition::kMismatch;
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(false));
  EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW)).Times(0);

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// In "never" update condition, send DBus signal only if RW is broken.
// Condition:
//   1. Update condition is "never".
//   2. In RO section.
//   3. RW is broken.
TEST_F(HammerUpdaterRWTest, Run_NeverUpdateRWBroken) {
  current_section_ = SectionName::RO;
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;

  EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW)).Times(0);
  {
    InSequence dummy;

    // Try to jump to RW, but still in RO.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(Return(true));
    // Send DBus signal, and reset the device again.
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareNeedUpdateSignal));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(Return(true));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(),
            HammerUpdater::RunStatus::kNeedReset);  // FAILURE
}

// In "never" update condition, do nothing if there is only normal update.
// Condition:
//   1. Update condition is "never".
//   2. In RO section.
//   3. RW is broken.
TEST_F(HammerUpdaterRWTest, Run_NeverUpdateNothing) {
  current_section_ = SectionName::RW;
  *update_condition_ = HammerUpdater::UpdateCondition::kNever;
  ON_CALL(*fw_updater_, VersionMismatch(_)).WillByDefault(Return(true));

  EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW)).Times(0);
  EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareNeedUpdateSignal))
      .Times(0);

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Return kInvalidFirmware if the layout of the firmware is changed.
// Condition:
//   1. The current section is Invalid.
TEST_F(HammerUpdaterRWTest, RunOnce_InvalidSection) {
  current_section_ = SectionName::Invalid;

  ASSERT_EQ(hammer_updater_->RunOnce(),
            HammerUpdater::RunStatus::kInvalidFirmware);
}

// Update the RW after JUMP_TO_RW failed.
// Condition:
//   1. In RO section.
//   2. RW does not need update.
//   3. Fails to jump to RW due to invalid signature.
TEST_F(HammerUpdaterRWTest, Run_UpdateRWAfterJumpToRWFailed) {
  current_section_ = SectionName::RO;

  {
    InSequence dummy;

    // First round: RW does not need update.  Attempt to jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(Return(true));

    // Second round: Jump to RW fails, so update RW. After update, again attempt
    // to jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(Return(true));

    // Third round: Again attempt to jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));

    // Fourth round: Check that jumping to RW was successful, and that
    // PostRWProcessing is called.
    EXPECT_CALL(*hammer_updater_, PostRWProcess())
        .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Inject Entropy.
// Condition:
//   1. In RO section at the begining.
//   2. RW does not need update.
//   3. RW is not locked.
//   4. Pairing failed at the first time.
//   5. After injecting entropy successfully, pairing is successful
TEST_F(HammerUpdaterRWTest, Run_InjectEntropy) {
  current_section_ = SectionName::RO;

  {
    InSequence dummy;

    // First round: RW does not need update.  Attempt to jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));

    // Second round: Entering RW section, and need to inject entropy.
    EXPECT_CALL(*hammer_updater_, PostRWProcess())
        .WillOnce(DoAll(Assign(&(task_->inject_entropy), true),
                        Return(HammerUpdater::RunStatus::kNeedReset)));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RO), Return(true)));

    // Third round: Inject entropy and reset again.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, InjectEntropy()).WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(Return(true));

    // Fourth round: Send JumpToRW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));

    // Fifth round: Post-RW processing is successful.
    EXPECT_CALL(*hammer_updater_, PostRWProcess())
        .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Update the RW and continue.
// Condition:
//   1. In RO section.
//   2. RW needs update.
//   3. RW is not locked.
TEST_F(HammerUpdaterRWTest, RunOnce_UpdateRW) {
  current_section_ = SectionName::RO;
  ON_CALL(*fw_updater_, VersionMismatch(SectionName::RW))
      .WillByDefault(Return(true));

  {
    InSequence dummy;
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW))
        .WillOnce(Return(true));
  }

  task_->update_rw = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNeedReset);
}

// Unlock the RW and reset.
// Condition:
//   1. In RO section.
//   2. RW needs update.
//   3. RW is locked.
TEST_F(HammerUpdaterRWTest, RunOnce_UnlockRW) {
  current_section_ = SectionName::RO;
  ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(1));
  ON_CALL(*fw_updater_, IsSectionLocked(SectionName::RW))
      .WillByDefault(Return(true));

  {
    InSequence dummy;
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, UnlockRW()).WillRepeatedly(Return(true));
  }

  task_->update_rw = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNeedReset);
}

// Jump to RW.
// Condition:
//   1. In RO section.
//   2. RW does not need update.
TEST_F(HammerUpdaterRWTest, RunOnce_JumpToRW) {
  current_section_ = SectionName::RO;

  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNeedJump);
}

// Complete RW jump.
// Condition:
//   1. In RW section.
//   2. RW jump flag is set.
TEST_F(HammerUpdaterRWTest, RunOnce_CompleteRWJump) {
  current_section_ = SectionName::RW;
  EXPECT_CALL(*hammer_updater_, PostRWProcess())
      .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));

  task_->post_rw_jump = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNoUpdate);
}

// Keep in RW.
// Condition:
//   1. In RW section.
//   2. RW does not need update.
TEST_F(HammerUpdaterRWTest, RunOnce_KeepInRW) {
  current_section_ = SectionName::RW;
  EXPECT_CALL(*hammer_updater_, PostRWProcess())
      .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));

  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNoUpdate);
}

// Reset to RO.
// Condition:
//   1. In RW section.
//   2. RW needs update.
TEST_F(HammerUpdaterRWTest, RunOnce_ResetToRO) {
  current_section_ = SectionName::RW;
  ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(1));
  ON_CALL(*fw_updater_, VersionMismatch(SectionName::RW))
      .WillByDefault(Return(true));

  task_->update_rw = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNeedReset);
}

// Update working RW with incompatible key firmware.
// Under the situation RO (key1, v1) RW (key1, v1),
// invoke hammerd with (key2, v2).
// Should print: "RW section needs update, but local image is
// incompatible. Continuing to post-RW process; maybe RO can
// be updated."
// Condition:
//   1. In RW section.
//   2. RW needs update.
//   3. Local image key_version is incompatible.
TEST_F(HammerUpdaterRWTest, RunOnce_UpdateWorkingRWIncompatibleKey) {
  current_section_ = SectionName::RW;
  ON_CALL(*fw_updater_, ValidKey()).WillByDefault(Return(false));
  ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(1));
  ON_CALL(*fw_updater_, VersionMismatch(SectionName::RW))
      .WillByDefault(Return(true));

  EXPECT_CALL(*hammer_updater_, PostRWProcess())
      .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));

  task_->update_rw = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kNoUpdate);
}

// Update corrupt RW with incompatible key firmware.
// Under the situation RO (key1, v1) RW (corrupt),
// invoke hammerd with (key2, v2).
// Should print: "RW section is unusable, but local image is
// incompatible. Giving up."
// Condition:
//   1. In RO section right after a failed JumpToRW.
//   2. RW needs update.
//   3. Local image key_version is incompatible.
TEST_F(HammerUpdaterRWTest, RunOnce_UpdateCorruptRWIncompatibleKey) {
  current_section_ = SectionName::RO;
  ON_CALL(*fw_updater_, ValidKey()).WillByDefault(Return(false));
  ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(1));
  ON_CALL(*fw_updater_, VersionMismatch(SectionName::RW))
      .WillByDefault(Return(true));

  task_->post_rw_jump = true;
  ASSERT_EQ(hammer_updater_->RunOnce(), HammerUpdater::RunStatus::kFatalError);
}

// Update locked RW section.
// Condition:
//   1. In RO section first.
//   2. A valid update is available for RW.
//   3. RW is locked.
TEST_F(HammerUpdaterRWTest, Run_UpdateLockedRW) {
  current_section_ = SectionName::RO;
  bool is_rw_locked = true;

  ON_CALL(*fw_updater_, IsSectionLocked(SectionName::RW))
      .WillByDefault(ReturnPointee(&is_rw_locked));

  {
    InSequence dummy;
    // First round: Find RW is locked, send UnlockRW command and reset.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, UnlockRW()).WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(DoAll(Assign(&is_rw_locked, false), Return(true)));
    // Second round: Update RW section, and reset again.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(Return(true));
    // Third round: Jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));
    // Fourth round: Run PostRWProcess.
    EXPECT_CALL(*hammer_updater_, PostRWProcess())
        .WillOnce(Return(HammerUpdater::RunStatus::kNoUpdate));
  }

  task_->update_rw = true;
  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Successfully Pair with Hammer.
TEST_F(HammerUpdaterPostRWTest, Pairing_Passed) {
  EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
      .WillOnce(Return(ChallengeStatus::kChallengePassed));
  EXPECT_EQ(hammer_updater_->Pair(), HammerUpdater::RunStatus::kNoUpdate);
}

// Hammer needs to inject entropy, and rollback is locked.
TEST_F(HammerUpdaterPostRWTest, Pairing_NeedEntropyRollbackLocked) {
  {
    InSequence dummy;
    EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
        .WillOnce(Return(ChallengeStatus::kNeedInjectEntropy));
    EXPECT_CALL(*fw_updater_, IsRollbackLocked()).WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, UnlockRollback()).WillOnce(Return(true));
  }
  EXPECT_EQ(hammer_updater_->Pair(), HammerUpdater::RunStatus::kNeedReset);
}

// Hammer needs to inject entropy, and rollback is not locked.
TEST_F(HammerUpdaterPostRWTest, Pairing_NeedEntropyRollbackUnlocked) {
  {
    InSequence dummy;
    EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
        .WillOnce(Return(ChallengeStatus::kNeedInjectEntropy));
    EXPECT_CALL(*fw_updater_, IsRollbackLocked()).WillOnce(Return(false));
  }
  EXPECT_EQ(hammer_updater_->Pair(), HammerUpdater::RunStatus::kNeedReset);
}

// Failed to pair with Hammer.
TEST_F(HammerUpdaterPostRWTest, Pairing_Failed) {
  EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
      .WillOnce(Return(ChallengeStatus::kChallengeFailed));
  EXPECT_EQ(hammer_updater_->Pair(), HammerUpdater::RunStatus::kFatalError);
}

// RO update is required and successful.
TEST_F(HammerUpdaterPostRWTest, ROUpdate_Passed) {
  {
    InSequence dummy;
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateStartedSignal));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RO))
        .WillOnce(Return(true));
  }

  task_->update_ro = true;
  EXPECT_EQ(hammer_updater_->UpdateRO(), HammerUpdater::RunStatus::kNeedReset);
}

// RO update is required and fails.
TEST_F(HammerUpdaterPostRWTest, ROUpdate_Failed) {
  {
    InSequence dummy;
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateStartedSignal));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RO))
        .WillOnce(Return(false));
  }

  task_->update_ro = true;
  EXPECT_EQ(hammer_updater_->UpdateRO(), HammerUpdater::RunStatus::kNeedReset);
}

// RO update is not possible.
TEST_F(HammerUpdaterPostRWTest, ROUpdate_NotPossible) {
  ON_CALL(*fw_updater_, IsSectionLocked(SectionName::RO))
      .WillByDefault(Return(true));
  EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RO)).Times(0);

  task_->update_ro = true;
  EXPECT_EQ(hammer_updater_->UpdateRO(), HammerUpdater::RunStatus::kNoUpdate);
}

// Skip updating to new key version on a normal device.
// Condition:
//   1. Rollback number is increased.
//   2. Key is changed.
//   3. RO is locked.
TEST_F(HammerUpdaterPostRWTest, Run_SkipUpdateWhenKeyChanged) {
  current_section_ = SectionName::RO;

  ON_CALL(*fw_updater_, IsSectionLocked(SectionName::RO))
      .WillByDefault(Return(true));
  ON_CALL(*fw_updater_, ValidKey()).WillByDefault(Return(false));
  ON_CALL(*fw_updater_, CompareRollback()).WillByDefault(Return(1));

  {
    InSequence dummy;

    // RW cannot be updated, since the key version is incorrect. Attempt to
    // jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));
    // Check that RO was not updated and jumping to RW was successful.
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RO)).Times(0);
    EXPECT_CALL(*fw_updater_, SendSubcommandReceiveResponse(
                                  UpdateExtraCommand::kTouchpadInfo, "", _,
                                  sizeof(TouchpadInfo), false))
        .WillOnce(WriteResponse(static_cast<void*>(&response_)));
    EXPECT_CALL(*fw_updater_, TransferTouchpadFirmware(_, _))
        .Times(0);  // Version matched, skip updating.
    EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
        .WillOnce(Return(ChallengeStatus::kChallengePassed));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Test updating to new key version on a dogfood device.
// Condition:
//   1. Rollback number is increased.
//   2. Key is changed.
//   3. RO is not locked.
TEST_F(HammerUpdaterPostRWTest, Run_KeyVersionUpdate) {
  current_section_ = SectionName::RO;
  bool valid_key = false;
  int rollback_cmp = 1;

  ON_CALL(*fw_updater_, ValidKey()).WillByDefault(ReturnPointee(&valid_key));
  ON_CALL(*fw_updater_, CompareRollback())
      .WillByDefault(ReturnPointee(&rollback_cmp));

  {
    InSequence dummy;

    // RW cannot be updated, since the key version is incorrect. Attempt to
    // jump to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));

    // After jumping to RW, RO will be updated. Reset afterwards.
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateStartedSignal));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(DoAll(Assign(&current_section_, SectionName::RO),
                        Assign(&valid_key, true), Return(true)));

    // Hammer resets back into RO. Now the key version is correct, and
    // RW will be updated. Reset afterwards.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kStayInRO))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_, TransferImage(SectionName::RW))
        .WillOnce(Return(true));
    EXPECT_CALL(*fw_updater_,
                SendSubcommand(UpdateExtraCommand::kImmediateReset))
        .WillOnce(DoAll(Assign(&rollback_cmp, 0), Return(true)));

    // Now both sections are updated. Jump from RO to RW.
    EXPECT_CALL(*fw_updater_, SendSubcommand(UpdateExtraCommand::kJumpToRW))
        .WillOnce(
            DoAll(Assign(&current_section_, SectionName::RW), Return(true)));

    // Check that jumping to RW was successful.
    EXPECT_CALL(*fw_updater_, SendSubcommandReceiveResponse(
                                  UpdateExtraCommand::kTouchpadInfo, "", _,
                                  sizeof(TouchpadInfo), false))
        .WillOnce(WriteResponse(static_cast<void*>(&response_)));
    EXPECT_CALL(*fw_updater_, TransferTouchpadFirmware(_, _))
        .Times(0);  // Version matched, skip updating.
    EXPECT_CALL(*pair_manager_, PairChallenge(fw_updater_, dbus_wrapper_))
        .WillOnce(Return(ChallengeStatus::kChallengePassed));
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateSucceededSignal));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}

// Test the return value if we can't get touchpad infomation.
TEST_F(HammerUpdaterPostRWTest, Run_FailToGetTouchpadInfo) {
  EXPECT_CALL(*fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kTouchpadInfo,
                                            "", _, sizeof(TouchpadInfo), false))
      .WillOnce(Return(false));

  ASSERT_EQ(hammer_updater_->RunTouchpadUpdater(),
            HammerUpdater::RunStatus::kNeedReset);
}

// Test logic of IC size matches with local firmware binary blob.
TEST_F(HammerUpdaterPostRWTest, Run_ICSizeMismatchAndStop) {
  // Make a mismatch response by setting a different firmware size.
  response_.fw_size += 9487;
  EXPECT_CALL(*fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kTouchpadInfo,
                                            "", _, sizeof(TouchpadInfo), false))
      .WillOnce(WriteResponse(reinterpret_cast<void*>(&response_)));

  ASSERT_EQ(hammer_updater_->RunTouchpadUpdater(),
            HammerUpdater::RunStatus::kTouchpadMismatched);
}

// Test logic of entire firmware blob hash matches one accepted in RW EC.
TEST_F(HammerUpdaterPostRWTest, Run_HashMismatchAndStop) {
  // Make a mismatch response by setting a different allowed_fw_hash.
  memset(response_.allowed_fw_hash, response_.allowed_fw_hash[0] + 0x5F,
         SHA256_DIGEST_LENGTH);
  EXPECT_CALL(*fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kTouchpadInfo,
                                            "", _, sizeof(TouchpadInfo), false))
      .WillOnce(WriteResponse(static_cast<void*>(&response_)));

  ASSERT_EQ(hammer_updater_->RunTouchpadUpdater(),
            HammerUpdater::RunStatus::kTouchpadMismatched);
}

// Test the return value if TransferTouchpadFirmware is failed.
TEST_F(HammerUpdaterPostRWTest, Run_FailToTransferFirmware) {
  response_.elan.fw_version -= 1;  // Make local fw_ver is newer than base.
  EXPECT_CALL(*fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kTouchpadInfo,
                                            "", _, sizeof(TouchpadInfo), false))
      .WillOnce(WriteResponse(static_cast<void*>(&response_)));
  EXPECT_CALL(*fw_updater_, TransferTouchpadFirmware(_, _))
      .WillOnce(Return(false));

  ASSERT_EQ(hammer_updater_->RunTouchpadUpdater(),
            HammerUpdater::RunStatus::kNeedReset);
}

// Update touchpad firmware on boot if the firmware is broken.
// Condition:
//   1. at_boot_ is True.
//   2. In RW section.
//   2. touchpad firmware is broken.
TEST_F(HammerUpdaterPostRWTest, Run_UpdateTouchpadOnBoot) {
  *at_boot_ = true;
  current_section_ = SectionName::RW;
  response_.elan.fw_version = kElanBrokenFwVersion;

  {
    InSequence dummy;
    // Check that RO was not updated and jumping to RW was successful.
    EXPECT_CALL(*fw_updater_, SendSubcommandReceiveResponse(
                                  UpdateExtraCommand::kTouchpadInfo, "", _,
                                  sizeof(TouchpadInfo), false))
        .WillOnce(WriteResponse(static_cast<void*>(&response_)));
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateStartedSignal));
    EXPECT_CALL(*fw_updater_, TransferTouchpadFirmware(_, _))
        .WillOnce(Return(true));
    EXPECT_CALL(*dbus_wrapper_, SendSignal(kBaseFirmwareUpdateSucceededSignal));
  }

  ExpectUsbConnections(AtLeast(1));
  ASSERT_EQ(hammer_updater_->Run(), HammerUpdater::RunStatus::kNoUpdate);
}
}  // namespace hammerd
