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