// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <windows.h>

#include <fstream>

#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/threading/platform_thread.h"
#include "chrome/installer/util/copy_tree_work_item.h"
#include "chrome/installer/util/work_item.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
  class CopyTreeWorkItemTest : public testing::Test {
   protected:
    virtual void SetUp() {
      ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
      ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
    }

    virtual void TearDown() {
      logging::CloseLogFile();
    }

    // the path to temporary directory used to contain the test operations
    base::ScopedTempDir test_dir_;
    base::ScopedTempDir temp_dir_;
  };

  // Simple function to dump some text into a new file.
  void CreateTextFile(const std::wstring& filename,
                      const std::wstring& contents) {
    std::ofstream file;
    file.open(filename.c_str());
    ASSERT_TRUE(file.is_open());
    file << contents;
    file.close();
  }

  bool IsFileInUse(const base::FilePath& path) {
    if (!base::PathExists(path))
      return false;

    HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS,
                                 NULL, NULL, OPEN_EXISTING, NULL, NULL);
    if (handle  == INVALID_HANDLE_VALUE)
      return true;

    CloseHandle(handle);
    return false;
  }

  // Simple function to read text from a file.
  std::wstring ReadTextFile(const std::wstring& filename) {
    WCHAR contents[64];
    std::wifstream file;
    file.open(filename.c_str());
    EXPECT_TRUE(file.is_open());
    file.getline(contents, 64);
    file.close();
    return std::wstring(contents);
  }

  wchar_t text_content_1[] = L"Gooooooooooooooooooooogle";
  wchar_t text_content_2[] = L"Overwrite Me";
};

// Copy one file from source to destination.
TEST_F(CopyTreeWorkItemTest, CopyFile) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From.txt");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create destination path
  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To.txt");

  // test Do()
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::ALWAYS,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));

  // test rollback()
  work_item->Rollback();

  EXPECT_FALSE(base::PathExists(file_name_to));
  EXPECT_TRUE(base::PathExists(file_name_from));
}

// Copy one file, overwriting the existing one in destination.
// Test with always_overwrite being true or false. The file is overwritten
// regardless since the content at destination file is different from source.
TEST_F(CopyTreeWorkItemTest, CopyFileOverwrite) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From.txt");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create destination file
  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To.txt");
  CreateTextFile(file_name_to.value(), text_content_2);
  ASSERT_TRUE(base::PathExists(file_name_to));

  // test Do() with always_overwrite being true.
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::ALWAYS,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));

  // test Do() with always_overwrite being false.
  // the file is still overwritten since the content is different.
  work_item.reset(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::IF_DIFFERENT,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));
}

// Copy one file, with the existing one in destination having the same
// content.
// If always_overwrite being true, the file is overwritten.
// If always_overwrite being false, the file is unchanged.
TEST_F(CopyTreeWorkItemTest, CopyFileSameContent) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From.txt");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create destination file
  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To.txt");
  CreateTextFile(file_name_to.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_to));

  // test Do() with always_overwrite being true.
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::ALWAYS,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  // Get the path of backup file
  base::FilePath backup_file(work_item->backup_path_.path());
  EXPECT_FALSE(backup_file.empty());
  backup_file = backup_file.AppendASCII("File_To.txt");

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  // we verify the file is overwritten by checking the existence of backup
  // file.
  EXPECT_TRUE(base::PathExists(backup_file));
  EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_1));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  // the backup file should be gone after rollback
  EXPECT_FALSE(base::PathExists(backup_file));

  // test Do() with always_overwrite being false. nothing should change.
  work_item.reset(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::IF_DIFFERENT,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  // we verify the file is not overwritten by checking that the backup
  // file does not exist.
  EXPECT_FALSE(base::PathExists(backup_file));

  // test rollback(). nothing should happen here.
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  EXPECT_FALSE(base::PathExists(backup_file));
}

// Copy one file and without rollback. Verify all temporary files are deleted.
TEST_F(CopyTreeWorkItemTest, CopyFileAndCleanup) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From.txt");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create destination file
  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To.txt");
  CreateTextFile(file_name_to.value(), text_content_2);
  ASSERT_TRUE(base::PathExists(file_name_to));

  base::FilePath backup_file;

  {
    // test Do().
    scoped_ptr<CopyTreeWorkItem> work_item(
        WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                         file_name_to,
                                         temp_dir_.path(),
                                         WorkItem::IF_DIFFERENT,
                                         base::FilePath()));

    EXPECT_TRUE(work_item->Do());

    // Get the path of backup file
    backup_file = work_item->backup_path_.path();
    EXPECT_FALSE(backup_file.empty());
    backup_file = backup_file.AppendASCII("File_To.txt");

    EXPECT_TRUE(base::PathExists(file_name_from));
    EXPECT_TRUE(base::PathExists(file_name_to));
    EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    // verify the file is moved to backup place.
    EXPECT_TRUE(base::PathExists(backup_file));
    EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_2));
  }

  // verify the backup file is cleaned up as well.
  EXPECT_FALSE(base::PathExists(backup_file));
}

// Copy one file, with the existing one in destination being used with
// overwrite option as IF_DIFFERENT. This destination-file-in-use should
// be moved to backup location after Do() and moved back after Rollback().
TEST_F(CopyTreeWorkItemTest, CopyFileInUse) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create an executable in destination path by copying ourself to it.
  wchar_t exe_full_path_str[MAX_PATH];
  ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
  base::FilePath exe_full_path(exe_full_path_str);

  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To");
  base::CopyFile(exe_full_path, file_name_to);
  ASSERT_TRUE(base::PathExists(file_name_to));

  VLOG(1) << "copy ourself from " << exe_full_path.value()
          << " to " << file_name_to.value();

  // Run the executable in destination path
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi = {0};
  ASSERT_TRUE(
      ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
                       NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
                       NULL, NULL, &si, &pi));

  // test Do().
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::IF_DIFFERENT,
                                       base::FilePath()));

  EXPECT_TRUE(work_item->Do());

  // Get the path of backup file
  base::FilePath backup_file(work_item->backup_path_.path());
  EXPECT_FALSE(backup_file.empty());
  backup_file = backup_file.AppendASCII("File_To");

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  // verify the file in used is moved to backup place.
  EXPECT_TRUE(base::PathExists(backup_file));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  // the backup file should be gone after rollback
  EXPECT_FALSE(base::PathExists(backup_file));

  TerminateProcess(pi.hProcess, 0);
  // make sure the handle is closed.
  EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
}

// Test overwrite option NEW_NAME_IF_IN_USE:
// 1. If destination file is in use, the source should be copied with the
//    new name after Do() and this new name file should be deleted
//    after rollback.
// 2. If destination file is not in use, the source should be copied in the
//    destination folder after Do() and should be rolled back after Rollback().
TEST_F(CopyTreeWorkItemTest, NewNameAndCopyTest) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create an executable in destination path by copying ourself to it.
  wchar_t exe_full_path_str[MAX_PATH];
  ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
  base::FilePath exe_full_path(exe_full_path_str);

  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to), alternate_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To");
  alternate_to = alternate_to.AppendASCII("Alternate_To");
  base::CopyFile(exe_full_path, file_name_to);
  ASSERT_TRUE(base::PathExists(file_name_to));

  VLOG(1) << "copy ourself from " << exe_full_path.value()
          << " to " << file_name_to.value();

  // Run the executable in destination path
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi = {0};
  ASSERT_TRUE(
      ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
                       NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
                       NULL, NULL, &si, &pi));

  // test Do().
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                       file_name_to,
                                       temp_dir_.path(),
                                       WorkItem::NEW_NAME_IF_IN_USE,
                                       alternate_to));

  EXPECT_TRUE(work_item->Do());

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  // verify that the backup path does not exist
  EXPECT_TRUE(work_item->backup_path_.path().empty());
  EXPECT_TRUE(base::ContentsEqual(file_name_from, alternate_to));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  EXPECT_TRUE(work_item->backup_path_.path().empty());
  // the alternate file should be gone after rollback
  EXPECT_FALSE(base::PathExists(alternate_to));

  TerminateProcess(pi.hProcess, 0);
  // make sure the handle is closed.
  EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  // Now the process has terminated, lets try overwriting the file again
  work_item.reset(WorkItem::CreateCopyTreeWorkItem(
      file_name_from, file_name_to,
      temp_dir_.path(), WorkItem::NEW_NAME_IF_IN_USE,
      alternate_to));
  if (IsFileInUse(file_name_to))
    base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2));
  // If file is still in use, the rest of the test will fail.
  ASSERT_FALSE(IsFileInUse(file_name_to));
  EXPECT_TRUE(work_item->Do());

  // Get the path of backup file
  base::FilePath backup_file(work_item->backup_path_.path());
  EXPECT_FALSE(backup_file.empty());
  backup_file = backup_file.AppendASCII("File_To");

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));
  // verify that the backup path does exist
  EXPECT_TRUE(base::PathExists(backup_file));
  EXPECT_FALSE(base::PathExists(alternate_to));

  // test rollback()
  work_item->Rollback();

  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  // the backup file should be gone after rollback
  EXPECT_FALSE(base::PathExists(backup_file));
  EXPECT_FALSE(base::PathExists(alternate_to));
}

// Test overwrite option IF_NOT_PRESENT:
// 1. If destination file/directory exist, the source should not be copied
// 2. If destination file/directory do not exist, the source should be copied
//    in the destination folder after Do() and should be rolled back after
//    Rollback().
// Flaky, http://crbug.com/59785.
TEST_F(CopyTreeWorkItemTest, DISABLED_IfNotPresentTest) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create an executable in destination path by copying ourself to it.
  wchar_t exe_full_path_str[MAX_PATH];
  ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
  base::FilePath exe_full_path(exe_full_path_str);

  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));
  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To");
  base::CopyFile(exe_full_path, file_name_to);
  ASSERT_TRUE(base::PathExists(file_name_to));

  // Get the path of backup file
  base::FilePath backup_file(temp_dir_.path());
  backup_file = backup_file.AppendASCII("File_To");

  // test Do().
  scoped_ptr<CopyTreeWorkItem> work_item(
      WorkItem::CreateCopyTreeWorkItem(
          file_name_from,
          file_name_to, temp_dir_.path(),
          WorkItem::IF_NOT_PRESENT,
          base::FilePath()));
  EXPECT_TRUE(work_item->Do());

  // verify that the source, destination have not changed and backup path
  // does not exist
  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  EXPECT_FALSE(base::PathExists(backup_file));

  // test rollback()
  work_item->Rollback();

  // verify that the source, destination have not changed and backup path
  // does not exist after rollback also
  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
  EXPECT_FALSE(base::PathExists(backup_file));

  // Now delete the destination and try copying the file again.
  base::DeleteFile(file_name_to, true);
  work_item.reset(WorkItem::CreateCopyTreeWorkItem(
      file_name_from, file_name_to,
      temp_dir_.path(), WorkItem::IF_NOT_PRESENT,
      base::FilePath()));
  EXPECT_TRUE(work_item->Do());

  // verify that the source, destination are the same and backup path
  // does not exist
  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_TRUE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
  EXPECT_FALSE(base::PathExists(backup_file));

  // test rollback()
  work_item->Rollback();

  // verify that the destination does not exist anymore
  EXPECT_TRUE(base::PathExists(file_name_from));
  EXPECT_FALSE(base::PathExists(file_name_to));
  EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
  EXPECT_FALSE(base::PathExists(backup_file));
}

// Copy one file without rollback. The existing one in destination is in use.
// Verify it is moved to backup location and stays there.
// Flaky, http://crbug.com/59783.
TEST_F(CopyTreeWorkItemTest, DISABLED_CopyFileInUseAndCleanup) {
  // Create source file
  base::FilePath file_name_from(test_dir_.path());
  file_name_from = file_name_from.AppendASCII("File_From");
  CreateTextFile(file_name_from.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from));

  // Create an executable in destination path by copying ourself to it.
  wchar_t exe_full_path_str[MAX_PATH];
  ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
  base::FilePath exe_full_path(exe_full_path_str);

  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
  base::CreateDirectory(dir_name_to);
  ASSERT_TRUE(base::PathExists(dir_name_to));

  base::FilePath file_name_to(dir_name_to);
  file_name_to = file_name_to.AppendASCII("File_To");
  base::CopyFile(exe_full_path, file_name_to);
  ASSERT_TRUE(base::PathExists(file_name_to));

  VLOG(1) << "copy ourself from " << exe_full_path.value()
          << " to " << file_name_to.value();

  // Run the executable in destination path
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi = {0};
  ASSERT_TRUE(
      ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
                       NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
                       NULL, NULL, &si, &pi));

  base::FilePath backup_file;

  // test Do().
  {
    scoped_ptr<CopyTreeWorkItem> work_item(
        WorkItem::CreateCopyTreeWorkItem(file_name_from,
                                         file_name_to,
                                         temp_dir_.path(),
                                         WorkItem::IF_DIFFERENT,
                                         base::FilePath()));

    EXPECT_TRUE(work_item->Do());

    // Get the path of backup file
    backup_file = work_item->backup_path_.path();
    EXPECT_FALSE(backup_file.empty());
    backup_file = backup_file.AppendASCII("File_To");

    EXPECT_TRUE(base::PathExists(file_name_from));
    EXPECT_TRUE(base::PathExists(file_name_to));
    EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    // verify the file in used is moved to backup place.
    EXPECT_TRUE(base::PathExists(backup_file));
    EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
  }

  // verify the file in used should be still at the backup place.
  EXPECT_TRUE(base::PathExists(backup_file));
  EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));

  TerminateProcess(pi.hProcess, 0);
  // make sure the handle is closed.
  EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
}

// Copy a tree from source to destination.
// Flaky, http://crbug.com/59784.
TEST_F(CopyTreeWorkItemTest, DISABLED_CopyTree) {
  // Create source tree
  base::FilePath dir_name_from(test_dir_.path());
  dir_name_from = dir_name_from.AppendASCII("from");
  base::CreateDirectory(dir_name_from);
  ASSERT_TRUE(base::PathExists(dir_name_from));

  base::FilePath dir_name_from_1(dir_name_from);
  dir_name_from_1 = dir_name_from_1.AppendASCII("1");
  base::CreateDirectory(dir_name_from_1);
  ASSERT_TRUE(base::PathExists(dir_name_from_1));

  base::FilePath dir_name_from_2(dir_name_from);
  dir_name_from_2 = dir_name_from_2.AppendASCII("2");
  base::CreateDirectory(dir_name_from_2);
  ASSERT_TRUE(base::PathExists(dir_name_from_2));

  base::FilePath file_name_from_1(dir_name_from_1);
  file_name_from_1 = file_name_from_1.AppendASCII("File_1.txt");
  CreateTextFile(file_name_from_1.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from_1));

  base::FilePath file_name_from_2(dir_name_from_2);
  file_name_from_2 = file_name_from_2.AppendASCII("File_2.txt");
  CreateTextFile(file_name_from_2.value(), text_content_1);
  ASSERT_TRUE(base::PathExists(file_name_from_2));

  base::FilePath dir_name_to(test_dir_.path());
  dir_name_to = dir_name_to.AppendASCII("to");

  // test Do()
  {
    scoped_ptr<CopyTreeWorkItem> work_item(
        WorkItem::CreateCopyTreeWorkItem(dir_name_from,
                                         dir_name_to,
                                         temp_dir_.path(),
                                         WorkItem::ALWAYS,
                                         base::FilePath()));

    EXPECT_TRUE(work_item->Do());
  }

  base::FilePath file_name_to_1(dir_name_to);
  file_name_to_1 = file_name_to_1.AppendASCII("1");
  file_name_to_1 = file_name_to_1.AppendASCII("File_1.txt");
  EXPECT_TRUE(base::PathExists(file_name_to_1));
  VLOG(1) << "compare " << file_name_from_1.value()
          << " and " << file_name_to_1.value();
  EXPECT_TRUE(base::ContentsEqual(file_name_from_1, file_name_to_1));

  base::FilePath file_name_to_2(dir_name_to);
  file_name_to_2 = file_name_to_2.AppendASCII("2");
  file_name_to_2 = file_name_to_2.AppendASCII("File_2.txt");
  EXPECT_TRUE(base::PathExists(file_name_to_2));
  VLOG(1) << "compare " << file_name_from_2.value()
          << " and " << file_name_to_2.value();
  EXPECT_TRUE(base::ContentsEqual(file_name_from_2, file_name_to_2));
}
