//
// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/common/download_action.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/location.h>
#include <base/strings/stringprintf.h>
#include <brillo/message_loops/fake_message_loop.h>
#include <brillo/message_loops/message_loop.h>

#include "update_engine/common/action_pipe.h"
#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/mock_download_action.h"
#include "update_engine/common/mock_http_fetcher.h"
#include "update_engine/common/mock_prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/cros/fake_p2p_manager_configuration.h"
#include "update_engine/cros/fake_system_state.h"
#include "update_engine/payload_consumer/mock_file_writer.h"
#include "update_engine/update_manager/fake_update_manager.h"

namespace chromeos_update_engine {

using base::FilePath;
using base::ReadFileToString;
using base::WriteFile;
using std::string;
using std::unique_ptr;
using testing::_;
using testing::AtLeast;
using testing::InSequence;
using testing::Return;
using testing::SetArgPointee;

class DownloadActionTest : public ::testing::Test {};

namespace {

class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate {
 public:
  DownloadActionTestProcessorDelegate()
      : processing_done_called_(false), expected_code_(ErrorCode::kSuccess) {}
  ~DownloadActionTestProcessorDelegate() override {
    EXPECT_TRUE(processing_done_called_);
  }
  void ProcessingDone(const ActionProcessor* processor,
                      ErrorCode code) override {
    brillo::MessageLoop::current()->BreakLoop();
    brillo::Blob found_data;
    ASSERT_TRUE(utils::ReadFile(path_, &found_data));
    if (expected_code_ != ErrorCode::kDownloadWriteError) {
      ASSERT_EQ(expected_data_.size(), found_data.size());
      for (unsigned i = 0; i < expected_data_.size(); i++) {
        EXPECT_EQ(expected_data_[i], found_data[i]);
      }
    }
    processing_done_called_ = true;
  }

  void ActionCompleted(ActionProcessor* processor,
                       AbstractAction* action,
                       ErrorCode code) override {
    const string type = action->Type();
    if (type == DownloadAction::StaticType()) {
      EXPECT_EQ(expected_code_, code);
      p2p_file_id_ = static_cast<DownloadAction*>(action)->p2p_file_id();
    } else {
      EXPECT_EQ(ErrorCode::kSuccess, code);
    }
  }

  string path_;
  brillo::Blob expected_data_;
  bool processing_done_called_;
  ErrorCode expected_code_;
  string p2p_file_id_;
};

class TestDirectFileWriter : public DirectFileWriter {
 public:
  TestDirectFileWriter() : fail_write_(0), current_write_(0) {}
  void set_fail_write(int fail_write) { fail_write_ = fail_write; }

  virtual bool Write(const void* bytes, size_t count) {
    if (++current_write_ == fail_write_) {
      return false;
    }
    return DirectFileWriter::Write(bytes, count);
  }

 private:
  // If positive, fail on the |fail_write_| call to Write.
  int fail_write_;
  int current_write_;
};

void StartProcessorInRunLoop(ActionProcessor* processor,
                             MockHttpFetcher* http_fetcher) {
  processor->StartProcessing();
  http_fetcher->SetOffset(1);
}

void TestWithData(const brillo::Blob& data,
                  int fail_write,
                  bool use_download_delegate) {
  brillo::FakeMessageLoop loop(nullptr);
  loop.SetAsCurrent();
  FakeSystemState fake_system_state;

  ScopedTempFile output_temp_file;
  TestDirectFileWriter writer;
  EXPECT_EQ(
      0, writer.Open(output_temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));
  writer.set_fail_write(fail_write);

  uint64_t size = data.size() - 1;
  InstallPlan install_plan;
  install_plan.payloads.push_back(
      {.size = size, .type = InstallPayloadType::kDelta});
  // We pull off the first byte from data and seek past it.
  EXPECT_TRUE(HashCalculator::RawHashOfBytes(
      &data[1], data.size() - 1, &install_plan.payloads[0].hash));
  install_plan.source_slot = 0;
  install_plan.target_slot = 1;
  // We mark both slots as bootable. Only the target slot should be unbootable
  // after the download starts.
  fake_system_state.fake_boot_control()->SetSlotBootable(
      install_plan.source_slot, true);
  fake_system_state.fake_boot_control()->SetSlotBootable(
      install_plan.target_slot, true);
  auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
  feeder_action->set_obj(install_plan);
  MockPrefs prefs;
  MockHttpFetcher* http_fetcher =
      new MockHttpFetcher(data.data(), data.size(), nullptr);
  // takes ownership of passed in HttpFetcher
  auto download_action =
      std::make_unique<DownloadAction>(&prefs,
                                       fake_system_state.boot_control(),
                                       fake_system_state.hardware(),
                                       &fake_system_state,
                                       http_fetcher,
                                       false /* interactive */);
  download_action->SetTestFileWriter(&writer);
  BondActions(feeder_action.get(), download_action.get());
  MockDownloadActionDelegate download_delegate;
  if (use_download_delegate) {
    InSequence s;
    download_action->set_delegate(&download_delegate);
    if (data.size() > kMockHttpFetcherChunkSize)
      EXPECT_CALL(download_delegate,
                  BytesReceived(_, kMockHttpFetcherChunkSize, _));
    EXPECT_CALL(download_delegate, BytesReceived(_, _, _)).Times(AtLeast(1));
    EXPECT_CALL(download_delegate, DownloadComplete())
        .Times(fail_write == 0 ? 1 : 0);
  }
  DownloadActionTestProcessorDelegate delegate;
  delegate.expected_code_ =
      (fail_write > 0) ? ErrorCode::kDownloadWriteError : ErrorCode::kSuccess;
  delegate.expected_data_ = brillo::Blob(data.begin() + 1, data.end());
  delegate.path_ = output_temp_file.path();
  ActionProcessor processor;
  processor.set_delegate(&delegate);
  processor.EnqueueAction(std::move(feeder_action));
  processor.EnqueueAction(std::move(download_action));

  loop.PostTask(FROM_HERE,
                base::Bind(&StartProcessorInRunLoop, &processor, http_fetcher));
  loop.Run();
  EXPECT_FALSE(loop.PendingTasks());

  EXPECT_TRUE(fake_system_state.fake_boot_control()->IsSlotBootable(
      install_plan.source_slot));
  EXPECT_FALSE(fake_system_state.fake_boot_control()->IsSlotBootable(
      install_plan.target_slot));
}
}  // namespace

TEST(DownloadActionTest, SimpleTest) {
  brillo::Blob small;
  const char* foo = "foo";
  small.insert(small.end(), foo, foo + strlen(foo));
  TestWithData(small,
               0,      // fail_write
               true);  // use_download_delegate
}

TEST(DownloadActionTest, LargeTest) {
  brillo::Blob big(5 * kMockHttpFetcherChunkSize);
  char c = '0';
  for (unsigned int i = 0; i < big.size(); i++) {
    big[i] = c;
    c = ('9' == c) ? '0' : c + 1;
  }
  TestWithData(big,
               0,      // fail_write
               true);  // use_download_delegate
}

TEST(DownloadActionTest, FailWriteTest) {
  brillo::Blob big(5 * kMockHttpFetcherChunkSize);
  char c = '0';
  for (unsigned int i = 0; i < big.size(); i++) {
    big[i] = c;
    c = ('9' == c) ? '0' : c + 1;
  }
  TestWithData(big,
               2,      // fail_write
               true);  // use_download_delegate
}

TEST(DownloadActionTest, NoDownloadDelegateTest) {
  brillo::Blob small;
  const char* foo = "foofoo";
  small.insert(small.end(), foo, foo + strlen(foo));
  TestWithData(small,
               0,       // fail_write
               false);  // use_download_delegate
}

TEST(DownloadActionTest, MultiPayloadProgressTest) {
  std::vector<brillo::Blob> payload_datas;
  // the first payload must be the largest, as it's the actual payload used by
  // the MockHttpFetcher for all downloaded data.
  payload_datas.emplace_back(4 * kMockHttpFetcherChunkSize + 256);
  payload_datas.emplace_back(2 * kMockHttpFetcherChunkSize);
  brillo::FakeMessageLoop loop(nullptr);
  loop.SetAsCurrent();
  FakeSystemState fake_system_state;
  EXPECT_CALL(*fake_system_state.mock_payload_state(), NextPayload())
      .WillOnce(Return(true));

  MockFileWriter mock_file_writer;
  EXPECT_CALL(mock_file_writer, Close()).WillRepeatedly(Return(0));
  EXPECT_CALL(mock_file_writer, Write(_, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(ErrorCode::kSuccess), Return(true)));

  InstallPlan install_plan;
  uint64_t total_expected_download_size{0};
  for (const auto& data : payload_datas) {
    uint64_t size = data.size();
    install_plan.payloads.push_back(
        {.size = size, .type = InstallPayloadType::kFull});
    total_expected_download_size += size;
  }
  auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
  feeder_action->set_obj(install_plan);
  MockPrefs prefs;
  MockHttpFetcher* http_fetcher = new MockHttpFetcher(
      payload_datas[0].data(), payload_datas[0].size(), nullptr);
  // takes ownership of passed in HttpFetcher
  auto download_action =
      std::make_unique<DownloadAction>(&prefs,
                                       fake_system_state.boot_control(),
                                       fake_system_state.hardware(),
                                       &fake_system_state,
                                       http_fetcher,
                                       false /* interactive */);
  download_action->SetTestFileWriter(&mock_file_writer);
  BondActions(feeder_action.get(), download_action.get());
  MockDownloadActionDelegate download_delegate;
  {
    InSequence s;
    download_action->set_delegate(&download_delegate);
    // these are hand-computed based on the payloads specified above
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              kMockHttpFetcherChunkSize,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              kMockHttpFetcherChunkSize * 2,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              kMockHttpFetcherChunkSize * 3,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              kMockHttpFetcherChunkSize * 4,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(256,
                              kMockHttpFetcherChunkSize * 4 + 256,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              kMockHttpFetcherChunkSize * 5 + 256,
                              total_expected_download_size));
    EXPECT_CALL(download_delegate,
                BytesReceived(kMockHttpFetcherChunkSize,
                              total_expected_download_size,
                              total_expected_download_size));
  }
  ActionProcessor processor;
  processor.EnqueueAction(std::move(feeder_action));
  processor.EnqueueAction(std::move(download_action));

  loop.PostTask(
      FROM_HERE,
      base::Bind(
          [](ActionProcessor* processor) { processor->StartProcessing(); },
          base::Unretained(&processor)));
  loop.Run();
  EXPECT_FALSE(loop.PendingTasks());
}

namespace {
class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
 public:
  void ProcessingStopped(const ActionProcessor* processor) {
    brillo::MessageLoop::current()->BreakLoop();
  }
};

void TerminateEarlyTestStarter(ActionProcessor* processor) {
  processor->StartProcessing();
  CHECK(processor->IsRunning());
  processor->StopProcessing();
}

void TestTerminateEarly(bool use_download_delegate) {
  brillo::FakeMessageLoop loop(nullptr);
  loop.SetAsCurrent();

  brillo::Blob data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2);
  memset(data.data(), 0, data.size());

  ScopedTempFile temp_file;
  {
    DirectFileWriter writer;
    EXPECT_EQ(0, writer.Open(temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));

    // takes ownership of passed in HttpFetcher
    auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
    InstallPlan install_plan;
    install_plan.payloads.resize(1);
    feeder_action->set_obj(install_plan);
    FakeSystemState fake_system_state_;
    MockPrefs prefs;
    auto download_action = std::make_unique<DownloadAction>(
        &prefs,
        fake_system_state_.boot_control(),
        fake_system_state_.hardware(),
        &fake_system_state_,
        new MockHttpFetcher(data.data(), data.size(), nullptr),
        false /* interactive */);
    download_action->SetTestFileWriter(&writer);
    MockDownloadActionDelegate download_delegate;
    if (use_download_delegate) {
      download_action->set_delegate(&download_delegate);
      EXPECT_CALL(download_delegate, BytesReceived(_, _, _)).Times(0);
    }
    TerminateEarlyTestProcessorDelegate delegate;
    ActionProcessor processor;
    processor.set_delegate(&delegate);
    BondActions(feeder_action.get(), download_action.get());
    processor.EnqueueAction(std::move(feeder_action));
    processor.EnqueueAction(std::move(download_action));

    loop.PostTask(FROM_HERE,
                  base::Bind(&TerminateEarlyTestStarter, &processor));
    loop.Run();
    EXPECT_FALSE(loop.PendingTasks());
  }

  // 1 or 0 chunks should have come through
  const off_t resulting_file_size(utils::FileSize(temp_file.path()));
  EXPECT_GE(resulting_file_size, 0);
  if (resulting_file_size != 0)
    EXPECT_EQ(kMockHttpFetcherChunkSize,
              static_cast<size_t>(resulting_file_size));
}

}  // namespace

TEST(DownloadActionTest, TerminateEarlyTest) {
  TestTerminateEarly(true);
}

TEST(DownloadActionTest, TerminateEarlyNoDownloadDelegateTest) {
  TestTerminateEarly(false);
}

class DownloadActionTestAction;

template <>
class ActionTraits<DownloadActionTestAction> {
 public:
  typedef InstallPlan OutputObjectType;
  typedef InstallPlan InputObjectType;
};

// This is a simple Action class for testing.
class DownloadActionTestAction : public Action<DownloadActionTestAction> {
 public:
  DownloadActionTestAction() = default;
  typedef InstallPlan InputObjectType;
  typedef InstallPlan OutputObjectType;
  ActionPipe<InstallPlan>* in_pipe() { return in_pipe_.get(); }
  ActionPipe<InstallPlan>* out_pipe() { return out_pipe_.get(); }
  ActionProcessor* processor() { return processor_; }
  void PerformAction() {
    ASSERT_TRUE(HasInputObject());
    EXPECT_TRUE(expected_input_object_ == GetInputObject());
    ASSERT_TRUE(processor());
    processor()->ActionComplete(this, ErrorCode::kSuccess);
  }
  static std::string StaticType() { return "DownloadActionTestAction"; }
  string Type() const { return StaticType(); }
  InstallPlan expected_input_object_;
};

namespace {
// This class is an ActionProcessorDelegate that simply terminates the
// run loop when the ActionProcessor has completed processing. It's used
// only by the test PassObjectOutTest.
class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate {
 public:
  void ProcessingDone(const ActionProcessor* processor,
                      ErrorCode code) override {
    brillo::MessageLoop::current()->BreakLoop();
  }
  void ActionCompleted(ActionProcessor* processor,
                       AbstractAction* action,
                       ErrorCode code) override {
    if (action->Type() == DownloadActionTestAction::StaticType()) {
      did_test_action_run_ = true;
    }
  }

  bool did_test_action_run_ = false;
};

}  // namespace

TEST(DownloadActionTest, PassObjectOutTest) {
  brillo::FakeMessageLoop loop(nullptr);
  loop.SetAsCurrent();

  DirectFileWriter writer;
  EXPECT_EQ(0, writer.Open("/dev/null", O_WRONLY | O_CREAT, 0));

  // takes ownership of passed in HttpFetcher
  InstallPlan install_plan;
  install_plan.payloads.push_back({.size = 1});
  EXPECT_TRUE(
      HashCalculator::RawHashOfData({'x'}, &install_plan.payloads[0].hash));
  auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
  feeder_action->set_obj(install_plan);
  MockPrefs prefs;
  FakeSystemState fake_system_state_;
  auto download_action =
      std::make_unique<DownloadAction>(&prefs,
                                       fake_system_state_.boot_control(),
                                       fake_system_state_.hardware(),
                                       &fake_system_state_,
                                       new MockHttpFetcher("x", 1, nullptr),
                                       false /* interactive */);
  download_action->SetTestFileWriter(&writer);

  auto test_action = std::make_unique<DownloadActionTestAction>();
  test_action->expected_input_object_ = install_plan;
  BondActions(feeder_action.get(), download_action.get());
  BondActions(download_action.get(), test_action.get());

  ActionProcessor processor;
  PassObjectOutTestProcessorDelegate delegate;
  processor.set_delegate(&delegate);
  processor.EnqueueAction(std::move(feeder_action));
  processor.EnqueueAction(std::move(download_action));
  processor.EnqueueAction(std::move(test_action));

  loop.PostTask(
      FROM_HERE,
      base::Bind(
          [](ActionProcessor* processor) { processor->StartProcessing(); },
          base::Unretained(&processor)));
  loop.Run();
  EXPECT_FALSE(loop.PendingTasks());

  EXPECT_EQ(true, delegate.did_test_action_run_);
}

// Test fixture for P2P tests.
class P2PDownloadActionTest : public testing::Test {
 protected:
  P2PDownloadActionTest()
      : start_at_offset_(0), fake_um_(fake_system_state_.fake_clock()) {}

  ~P2PDownloadActionTest() override {}

  // Derived from testing::Test.
  void SetUp() override { loop_.SetAsCurrent(); }

  // Derived from testing::Test.
  void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }

  // To be called by tests to setup the download. The
  // |starting_offset| parameter is for where to resume.
  void SetupDownload(off_t starting_offset) {
    start_at_offset_ = starting_offset;
    // Prepare data 10 kB of data.
    data_.clear();
    for (unsigned int i = 0; i < 10 * 1000; i++)
      data_ += 'a' + (i % 25);

    // Setup p2p.
    FakeP2PManagerConfiguration* test_conf = new FakeP2PManagerConfiguration();
    p2p_manager_.reset(P2PManager::Construct(test_conf,
                                             nullptr,
                                             &fake_um_,
                                             "cros_au",
                                             3,
                                             base::TimeDelta::FromDays(5)));
    fake_system_state_.set_p2p_manager(p2p_manager_.get());
  }

  // To be called by tests to perform the download. The
  // |use_p2p_to_share| parameter is used to indicate whether the
  // payload should be shared via p2p.
  void StartDownload(bool use_p2p_to_share) {
    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
                GetUsingP2PForSharing())
        .WillRepeatedly(Return(use_p2p_to_share));

    ScopedTempFile output_temp_file;
    TestDirectFileWriter writer;
    EXPECT_EQ(
        0, writer.Open(output_temp_file.path().c_str(), O_WRONLY | O_CREAT, 0));
    InstallPlan install_plan;
    install_plan.payloads.push_back(
        {.size = data_.length(),
         .hash = {'1', '2', '3', '4', 'h', 'a', 's', 'h'}});
    auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>();
    feeder_action->set_obj(install_plan);
    MockPrefs prefs;
    // Note that DownloadAction takes ownership of the passed in HttpFetcher.
    auto download_action = std::make_unique<DownloadAction>(
        &prefs,
        fake_system_state_.boot_control(),
        fake_system_state_.hardware(),
        &fake_system_state_,
        new MockHttpFetcher(data_.c_str(), data_.length(), nullptr),
        false /* interactive */);
    auto http_fetcher = download_action->http_fetcher();
    download_action->SetTestFileWriter(&writer);
    BondActions(feeder_action.get(), download_action.get());
    delegate_.expected_data_ =
        brillo::Blob(data_.begin() + start_at_offset_, data_.end());
    delegate_.path_ = output_temp_file.path();
    processor_.set_delegate(&delegate_);
    processor_.EnqueueAction(std::move(feeder_action));
    processor_.EnqueueAction(std::move(download_action));

    loop_.PostTask(
        FROM_HERE,
        base::Bind(
            [](P2PDownloadActionTest* action_test, HttpFetcher* http_fetcher) {
              action_test->processor_.StartProcessing();
              http_fetcher->SetOffset(action_test->start_at_offset_);
            },
            base::Unretained(this),
            base::Unretained(http_fetcher)));
    loop_.Run();
  }

  // Mainloop used to make StartDownload() synchronous.
  brillo::FakeMessageLoop loop_{nullptr};

  // Delegate that is passed to the ActionProcessor.
  DownloadActionTestProcessorDelegate delegate_;

  // The P2PManager used in the test.
  unique_ptr<P2PManager> p2p_manager_;

  // The ActionProcessor used for running the actions.
  ActionProcessor processor_;

  // A fake system state.
  FakeSystemState fake_system_state_;

  // The data being downloaded.
  string data_;

 private:
  // The requested starting offset passed to SetupDownload().
  off_t start_at_offset_;

  chromeos_update_manager::FakeUpdateManager fake_um_;
};

TEST_F(P2PDownloadActionTest, IsWrittenTo) {
  SetupDownload(0);     // starting_offset
  StartDownload(true);  // use_p2p_to_share

  // Check the p2p file and its content matches what was sent.
  string file_id = delegate_.p2p_file_id_;
  EXPECT_NE("", file_id);
  EXPECT_EQ(static_cast<int>(data_.length()),
            p2p_manager_->FileGetSize(file_id));
  EXPECT_EQ(static_cast<int>(data_.length()),
            p2p_manager_->FileGetExpectedSize(file_id));
  string p2p_file_contents;
  EXPECT_TRUE(
      ReadFileToString(p2p_manager_->FileGetPath(file_id), &p2p_file_contents));
  EXPECT_EQ(data_, p2p_file_contents);
}

TEST_F(P2PDownloadActionTest, DeleteIfHoleExists) {
  SetupDownload(1000);  // starting_offset
  StartDownload(true);  // use_p2p_to_share

  // DownloadAction should convey that the file is not being shared.
  // and that we don't have any p2p files.
  EXPECT_EQ(delegate_.p2p_file_id_, "");
  EXPECT_EQ(p2p_manager_->CountSharedFiles(), 0);
}

TEST_F(P2PDownloadActionTest, CanAppend) {
  SetupDownload(1000);  // starting_offset

  // Prepare the file with existing data before starting to write to
  // it via DownloadAction.
  string file_id = utils::CalculateP2PFileId(
      {'1', '2', '3', '4', 'h', 'a', 's', 'h'}, data_.length());
  ASSERT_TRUE(p2p_manager_->FileShare(file_id, data_.length()));
  string existing_data;
  for (unsigned int i = 0; i < 1000; i++)
    existing_data += '0' + (i % 10);
  ASSERT_EQ(
      WriteFile(
          p2p_manager_->FileGetPath(file_id), existing_data.c_str(), 1000),
      1000);

  StartDownload(true);  // use_p2p_to_share

  // DownloadAction should convey the same file_id and the file should
  // have the expected size.
  EXPECT_EQ(delegate_.p2p_file_id_, file_id);
  EXPECT_EQ(static_cast<ssize_t>(data_.length()),
            p2p_manager_->FileGetSize(file_id));
  EXPECT_EQ(static_cast<ssize_t>(data_.length()),
            p2p_manager_->FileGetExpectedSize(file_id));
  string p2p_file_contents;
  // Check that the first 1000 bytes wasn't touched and that we
  // appended the remaining as appropriate.
  EXPECT_TRUE(
      ReadFileToString(p2p_manager_->FileGetPath(file_id), &p2p_file_contents));
  EXPECT_EQ(existing_data, p2p_file_contents.substr(0, 1000));
  EXPECT_EQ(data_.substr(1000), p2p_file_contents.substr(1000));
}

TEST_F(P2PDownloadActionTest, DeletePartialP2PFileIfResumingWithoutP2P) {
  SetupDownload(1000);  // starting_offset

  // Prepare the file with all existing data before starting to write
  // to it via DownloadAction.
  string file_id = utils::CalculateP2PFileId(
      {'1', '2', '3', '4', 'h', 'a', 's', 'h'}, data_.length());
  ASSERT_TRUE(p2p_manager_->FileShare(file_id, data_.length()));
  string existing_data;
  for (unsigned int i = 0; i < 1000; i++)
    existing_data += '0' + (i % 10);
  ASSERT_EQ(
      WriteFile(
          p2p_manager_->FileGetPath(file_id), existing_data.c_str(), 1000),
      1000);

  // Check that the file is there.
  EXPECT_EQ(1000, p2p_manager_->FileGetSize(file_id));
  EXPECT_EQ(1, p2p_manager_->CountSharedFiles());

  StartDownload(false);  // use_p2p_to_share

  // DownloadAction should have deleted the p2p file. Check that it's gone.
  EXPECT_EQ(-1, p2p_manager_->FileGetSize(file_id));
  EXPECT_EQ(0, p2p_manager_->CountSharedFiles());
}

}  // namespace chromeos_update_engine
