//
// 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/payload_consumer/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_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/fake_p2p_manager_configuration.h"
#include "update_engine/fake_system_state.h"
#include "update_engine/mock_file_writer.h"
#include "update_engine/payload_consumer/mock_download_action.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 test_utils::ScopedTempFile;
using testing::AtLeast;
using testing::InSequence;
using testing::Return;
using testing::SetArgPointee;
using testing::_;

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;

  // TODO(adlr): see if we need a different file for build bots
  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
