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