Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <windows.h>
      6 
      7 #include <fstream>
      8 
      9 #include "base/base_paths.h"
     10 #include "base/file_util.h"
     11 #include "base/files/scoped_temp_dir.h"
     12 #include "base/logging.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/path_service.h"
     15 #include "base/strings/string_util.h"
     16 #include "base/threading/platform_thread.h"
     17 #include "chrome/installer/util/copy_tree_work_item.h"
     18 #include "chrome/installer/util/work_item.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace {
     22   class CopyTreeWorkItemTest : public testing::Test {
     23    protected:
     24     virtual void SetUp() {
     25       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     26       ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
     27     }
     28 
     29     virtual void TearDown() {
     30       logging::CloseLogFile();
     31     }
     32 
     33     // the path to temporary directory used to contain the test operations
     34     base::ScopedTempDir test_dir_;
     35     base::ScopedTempDir temp_dir_;
     36   };
     37 
     38   // Simple function to dump some text into a new file.
     39   void CreateTextFile(const std::wstring& filename,
     40                       const std::wstring& contents) {
     41     std::ofstream file;
     42     file.open(filename.c_str());
     43     ASSERT_TRUE(file.is_open());
     44     file << contents;
     45     file.close();
     46   }
     47 
     48   bool IsFileInUse(const base::FilePath& path) {
     49     if (!base::PathExists(path))
     50       return false;
     51 
     52     HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS,
     53                                  NULL, NULL, OPEN_EXISTING, NULL, NULL);
     54     if (handle  == INVALID_HANDLE_VALUE)
     55       return true;
     56 
     57     CloseHandle(handle);
     58     return false;
     59   }
     60 
     61   // Simple function to read text from a file.
     62   std::wstring ReadTextFile(const std::wstring& filename) {
     63     WCHAR contents[64];
     64     std::wifstream file;
     65     file.open(filename.c_str());
     66     EXPECT_TRUE(file.is_open());
     67     file.getline(contents, 64);
     68     file.close();
     69     return std::wstring(contents);
     70   }
     71 
     72   wchar_t text_content_1[] = L"Gooooooooooooooooooooogle";
     73   wchar_t text_content_2[] = L"Overwrite Me";
     74 };
     75 
     76 // Copy one file from source to destination.
     77 TEST_F(CopyTreeWorkItemTest, CopyFile) {
     78   // Create source file
     79   base::FilePath file_name_from(test_dir_.path());
     80   file_name_from = file_name_from.AppendASCII("File_From.txt");
     81   CreateTextFile(file_name_from.value(), text_content_1);
     82   ASSERT_TRUE(base::PathExists(file_name_from));
     83 
     84   // Create destination path
     85   base::FilePath dir_name_to(test_dir_.path());
     86   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
     87   base::CreateDirectory(dir_name_to);
     88   ASSERT_TRUE(base::PathExists(dir_name_to));
     89 
     90   base::FilePath file_name_to(dir_name_to);
     91   file_name_to = file_name_to.AppendASCII("File_To.txt");
     92 
     93   // test Do()
     94   scoped_ptr<CopyTreeWorkItem> work_item(
     95       WorkItem::CreateCopyTreeWorkItem(file_name_from,
     96                                        file_name_to,
     97                                        temp_dir_.path(),
     98                                        WorkItem::ALWAYS,
     99                                        base::FilePath()));
    100 
    101   EXPECT_TRUE(work_item->Do());
    102 
    103   EXPECT_TRUE(base::PathExists(file_name_from));
    104   EXPECT_TRUE(base::PathExists(file_name_to));
    105   EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));
    106 
    107   // test rollback()
    108   work_item->Rollback();
    109 
    110   EXPECT_FALSE(base::PathExists(file_name_to));
    111   EXPECT_TRUE(base::PathExists(file_name_from));
    112 }
    113 
    114 // Copy one file, overwriting the existing one in destination.
    115 // Test with always_overwrite being true or false. The file is overwritten
    116 // regardless since the content at destination file is different from source.
    117 TEST_F(CopyTreeWorkItemTest, CopyFileOverwrite) {
    118   // Create source file
    119   base::FilePath file_name_from(test_dir_.path());
    120   file_name_from = file_name_from.AppendASCII("File_From.txt");
    121   CreateTextFile(file_name_from.value(), text_content_1);
    122   ASSERT_TRUE(base::PathExists(file_name_from));
    123 
    124   // Create destination file
    125   base::FilePath dir_name_to(test_dir_.path());
    126   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    127   base::CreateDirectory(dir_name_to);
    128   ASSERT_TRUE(base::PathExists(dir_name_to));
    129 
    130   base::FilePath file_name_to(dir_name_to);
    131   file_name_to = file_name_to.AppendASCII("File_To.txt");
    132   CreateTextFile(file_name_to.value(), text_content_2);
    133   ASSERT_TRUE(base::PathExists(file_name_to));
    134 
    135   // test Do() with always_overwrite being true.
    136   scoped_ptr<CopyTreeWorkItem> work_item(
    137       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    138                                        file_name_to,
    139                                        temp_dir_.path(),
    140                                        WorkItem::ALWAYS,
    141                                        base::FilePath()));
    142 
    143   EXPECT_TRUE(work_item->Do());
    144 
    145   EXPECT_TRUE(base::PathExists(file_name_from));
    146   EXPECT_TRUE(base::PathExists(file_name_to));
    147   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    148   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    149 
    150   // test rollback()
    151   work_item->Rollback();
    152 
    153   EXPECT_TRUE(base::PathExists(file_name_from));
    154   EXPECT_TRUE(base::PathExists(file_name_to));
    155   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    156   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));
    157 
    158   // test Do() with always_overwrite being false.
    159   // the file is still overwritten since the content is different.
    160   work_item.reset(
    161       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    162                                        file_name_to,
    163                                        temp_dir_.path(),
    164                                        WorkItem::IF_DIFFERENT,
    165                                        base::FilePath()));
    166 
    167   EXPECT_TRUE(work_item->Do());
    168 
    169   EXPECT_TRUE(base::PathExists(file_name_from));
    170   EXPECT_TRUE(base::PathExists(file_name_to));
    171   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    172   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    173 
    174   // test rollback()
    175   work_item->Rollback();
    176 
    177   EXPECT_TRUE(base::PathExists(file_name_from));
    178   EXPECT_TRUE(base::PathExists(file_name_to));
    179   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    180   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));
    181 }
    182 
    183 // Copy one file, with the existing one in destination having the same
    184 // content.
    185 // If always_overwrite being true, the file is overwritten.
    186 // If always_overwrite being false, the file is unchanged.
    187 TEST_F(CopyTreeWorkItemTest, CopyFileSameContent) {
    188   // Create source file
    189   base::FilePath file_name_from(test_dir_.path());
    190   file_name_from = file_name_from.AppendASCII("File_From.txt");
    191   CreateTextFile(file_name_from.value(), text_content_1);
    192   ASSERT_TRUE(base::PathExists(file_name_from));
    193 
    194   // Create destination file
    195   base::FilePath dir_name_to(test_dir_.path());
    196   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    197   base::CreateDirectory(dir_name_to);
    198   ASSERT_TRUE(base::PathExists(dir_name_to));
    199 
    200   base::FilePath file_name_to(dir_name_to);
    201   file_name_to = file_name_to.AppendASCII("File_To.txt");
    202   CreateTextFile(file_name_to.value(), text_content_1);
    203   ASSERT_TRUE(base::PathExists(file_name_to));
    204 
    205   // test Do() with always_overwrite being true.
    206   scoped_ptr<CopyTreeWorkItem> work_item(
    207       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    208                                        file_name_to,
    209                                        temp_dir_.path(),
    210                                        WorkItem::ALWAYS,
    211                                        base::FilePath()));
    212 
    213   EXPECT_TRUE(work_item->Do());
    214 
    215   // Get the path of backup file
    216   base::FilePath backup_file(work_item->backup_path_.path());
    217   EXPECT_FALSE(backup_file.empty());
    218   backup_file = backup_file.AppendASCII("File_To.txt");
    219 
    220   EXPECT_TRUE(base::PathExists(file_name_from));
    221   EXPECT_TRUE(base::PathExists(file_name_to));
    222   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    223   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    224   // we verify the file is overwritten by checking the existence of backup
    225   // file.
    226   EXPECT_TRUE(base::PathExists(backup_file));
    227   EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_1));
    228 
    229   // test rollback()
    230   work_item->Rollback();
    231 
    232   EXPECT_TRUE(base::PathExists(file_name_from));
    233   EXPECT_TRUE(base::PathExists(file_name_to));
    234   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    235   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    236   // the backup file should be gone after rollback
    237   EXPECT_FALSE(base::PathExists(backup_file));
    238 
    239   // test Do() with always_overwrite being false. nothing should change.
    240   work_item.reset(
    241       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    242                                        file_name_to,
    243                                        temp_dir_.path(),
    244                                        WorkItem::IF_DIFFERENT,
    245                                        base::FilePath()));
    246 
    247   EXPECT_TRUE(work_item->Do());
    248 
    249   EXPECT_TRUE(base::PathExists(file_name_from));
    250   EXPECT_TRUE(base::PathExists(file_name_to));
    251   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    252   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    253   // we verify the file is not overwritten by checking that the backup
    254   // file does not exist.
    255   EXPECT_FALSE(base::PathExists(backup_file));
    256 
    257   // test rollback(). nothing should happen here.
    258   work_item->Rollback();
    259 
    260   EXPECT_TRUE(base::PathExists(file_name_from));
    261   EXPECT_TRUE(base::PathExists(file_name_to));
    262   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    263   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    264   EXPECT_FALSE(base::PathExists(backup_file));
    265 }
    266 
    267 // Copy one file and without rollback. Verify all temporary files are deleted.
    268 TEST_F(CopyTreeWorkItemTest, CopyFileAndCleanup) {
    269   // Create source file
    270   base::FilePath file_name_from(test_dir_.path());
    271   file_name_from = file_name_from.AppendASCII("File_From.txt");
    272   CreateTextFile(file_name_from.value(), text_content_1);
    273   ASSERT_TRUE(base::PathExists(file_name_from));
    274 
    275   // Create destination file
    276   base::FilePath dir_name_to(test_dir_.path());
    277   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    278   base::CreateDirectory(dir_name_to);
    279   ASSERT_TRUE(base::PathExists(dir_name_to));
    280 
    281   base::FilePath file_name_to(dir_name_to);
    282   file_name_to = file_name_to.AppendASCII("File_To.txt");
    283   CreateTextFile(file_name_to.value(), text_content_2);
    284   ASSERT_TRUE(base::PathExists(file_name_to));
    285 
    286   base::FilePath backup_file;
    287 
    288   {
    289     // test Do().
    290     scoped_ptr<CopyTreeWorkItem> work_item(
    291         WorkItem::CreateCopyTreeWorkItem(file_name_from,
    292                                          file_name_to,
    293                                          temp_dir_.path(),
    294                                          WorkItem::IF_DIFFERENT,
    295                                          base::FilePath()));
    296 
    297     EXPECT_TRUE(work_item->Do());
    298 
    299     // Get the path of backup file
    300     backup_file = work_item->backup_path_.path();
    301     EXPECT_FALSE(backup_file.empty());
    302     backup_file = backup_file.AppendASCII("File_To.txt");
    303 
    304     EXPECT_TRUE(base::PathExists(file_name_from));
    305     EXPECT_TRUE(base::PathExists(file_name_to));
    306     EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    307     EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    308     // verify the file is moved to backup place.
    309     EXPECT_TRUE(base::PathExists(backup_file));
    310     EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_2));
    311   }
    312 
    313   // verify the backup file is cleaned up as well.
    314   EXPECT_FALSE(base::PathExists(backup_file));
    315 }
    316 
    317 // Copy one file, with the existing one in destination being used with
    318 // overwrite option as IF_DIFFERENT. This destination-file-in-use should
    319 // be moved to backup location after Do() and moved back after Rollback().
    320 TEST_F(CopyTreeWorkItemTest, CopyFileInUse) {
    321   // Create source file
    322   base::FilePath file_name_from(test_dir_.path());
    323   file_name_from = file_name_from.AppendASCII("File_From");
    324   CreateTextFile(file_name_from.value(), text_content_1);
    325   ASSERT_TRUE(base::PathExists(file_name_from));
    326 
    327   // Create an executable in destination path by copying ourself to it.
    328   wchar_t exe_full_path_str[MAX_PATH];
    329   ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
    330   base::FilePath exe_full_path(exe_full_path_str);
    331 
    332   base::FilePath dir_name_to(test_dir_.path());
    333   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    334   base::CreateDirectory(dir_name_to);
    335   ASSERT_TRUE(base::PathExists(dir_name_to));
    336 
    337   base::FilePath file_name_to(dir_name_to);
    338   file_name_to = file_name_to.AppendASCII("File_To");
    339   base::CopyFile(exe_full_path, file_name_to);
    340   ASSERT_TRUE(base::PathExists(file_name_to));
    341 
    342   VLOG(1) << "copy ourself from " << exe_full_path.value()
    343           << " to " << file_name_to.value();
    344 
    345   // Run the executable in destination path
    346   STARTUPINFOW si = {sizeof(si)};
    347   PROCESS_INFORMATION pi = {0};
    348   ASSERT_TRUE(
    349       ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
    350                        NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
    351                        NULL, NULL, &si, &pi));
    352 
    353   // test Do().
    354   scoped_ptr<CopyTreeWorkItem> work_item(
    355       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    356                                        file_name_to,
    357                                        temp_dir_.path(),
    358                                        WorkItem::IF_DIFFERENT,
    359                                        base::FilePath()));
    360 
    361   EXPECT_TRUE(work_item->Do());
    362 
    363   // Get the path of backup file
    364   base::FilePath backup_file(work_item->backup_path_.path());
    365   EXPECT_FALSE(backup_file.empty());
    366   backup_file = backup_file.AppendASCII("File_To");
    367 
    368   EXPECT_TRUE(base::PathExists(file_name_from));
    369   EXPECT_TRUE(base::PathExists(file_name_to));
    370   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    371   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    372   // verify the file in used is moved to backup place.
    373   EXPECT_TRUE(base::PathExists(backup_file));
    374   EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
    375 
    376   // test rollback()
    377   work_item->Rollback();
    378 
    379   EXPECT_TRUE(base::PathExists(file_name_from));
    380   EXPECT_TRUE(base::PathExists(file_name_to));
    381   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    382   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    383   // the backup file should be gone after rollback
    384   EXPECT_FALSE(base::PathExists(backup_file));
    385 
    386   TerminateProcess(pi.hProcess, 0);
    387   // make sure the handle is closed.
    388   EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
    389   CloseHandle(pi.hProcess);
    390   CloseHandle(pi.hThread);
    391 }
    392 
    393 // Test overwrite option NEW_NAME_IF_IN_USE:
    394 // 1. If destination file is in use, the source should be copied with the
    395 //    new name after Do() and this new name file should be deleted
    396 //    after rollback.
    397 // 2. If destination file is not in use, the source should be copied in the
    398 //    destination folder after Do() and should be rolled back after Rollback().
    399 TEST_F(CopyTreeWorkItemTest, NewNameAndCopyTest) {
    400   // Create source file
    401   base::FilePath file_name_from(test_dir_.path());
    402   file_name_from = file_name_from.AppendASCII("File_From");
    403   CreateTextFile(file_name_from.value(), text_content_1);
    404   ASSERT_TRUE(base::PathExists(file_name_from));
    405 
    406   // Create an executable in destination path by copying ourself to it.
    407   wchar_t exe_full_path_str[MAX_PATH];
    408   ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
    409   base::FilePath exe_full_path(exe_full_path_str);
    410 
    411   base::FilePath dir_name_to(test_dir_.path());
    412   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    413   base::CreateDirectory(dir_name_to);
    414   ASSERT_TRUE(base::PathExists(dir_name_to));
    415 
    416   base::FilePath file_name_to(dir_name_to), alternate_to(dir_name_to);
    417   file_name_to = file_name_to.AppendASCII("File_To");
    418   alternate_to = alternate_to.AppendASCII("Alternate_To");
    419   base::CopyFile(exe_full_path, file_name_to);
    420   ASSERT_TRUE(base::PathExists(file_name_to));
    421 
    422   VLOG(1) << "copy ourself from " << exe_full_path.value()
    423           << " to " << file_name_to.value();
    424 
    425   // Run the executable in destination path
    426   STARTUPINFOW si = {sizeof(si)};
    427   PROCESS_INFORMATION pi = {0};
    428   ASSERT_TRUE(
    429       ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
    430                        NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
    431                        NULL, NULL, &si, &pi));
    432 
    433   // test Do().
    434   scoped_ptr<CopyTreeWorkItem> work_item(
    435       WorkItem::CreateCopyTreeWorkItem(file_name_from,
    436                                        file_name_to,
    437                                        temp_dir_.path(),
    438                                        WorkItem::NEW_NAME_IF_IN_USE,
    439                                        alternate_to));
    440 
    441   EXPECT_TRUE(work_item->Do());
    442 
    443   EXPECT_TRUE(base::PathExists(file_name_from));
    444   EXPECT_TRUE(base::PathExists(file_name_to));
    445   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    446   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    447   // verify that the backup path does not exist
    448   EXPECT_TRUE(work_item->backup_path_.path().empty());
    449   EXPECT_TRUE(base::ContentsEqual(file_name_from, alternate_to));
    450 
    451   // test rollback()
    452   work_item->Rollback();
    453 
    454   EXPECT_TRUE(base::PathExists(file_name_from));
    455   EXPECT_TRUE(base::PathExists(file_name_to));
    456   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    457   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    458   EXPECT_TRUE(work_item->backup_path_.path().empty());
    459   // the alternate file should be gone after rollback
    460   EXPECT_FALSE(base::PathExists(alternate_to));
    461 
    462   TerminateProcess(pi.hProcess, 0);
    463   // make sure the handle is closed.
    464   EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
    465   CloseHandle(pi.hProcess);
    466   CloseHandle(pi.hThread);
    467 
    468   // Now the process has terminated, lets try overwriting the file again
    469   work_item.reset(WorkItem::CreateCopyTreeWorkItem(
    470       file_name_from, file_name_to,
    471       temp_dir_.path(), WorkItem::NEW_NAME_IF_IN_USE,
    472       alternate_to));
    473   if (IsFileInUse(file_name_to))
    474     base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2));
    475   // If file is still in use, the rest of the test will fail.
    476   ASSERT_FALSE(IsFileInUse(file_name_to));
    477   EXPECT_TRUE(work_item->Do());
    478 
    479   // Get the path of backup file
    480   base::FilePath backup_file(work_item->backup_path_.path());
    481   EXPECT_FALSE(backup_file.empty());
    482   backup_file = backup_file.AppendASCII("File_To");
    483 
    484   EXPECT_TRUE(base::PathExists(file_name_from));
    485   EXPECT_TRUE(base::PathExists(file_name_to));
    486   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    487   EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));
    488   // verify that the backup path does exist
    489   EXPECT_TRUE(base::PathExists(backup_file));
    490   EXPECT_FALSE(base::PathExists(alternate_to));
    491 
    492   // test rollback()
    493   work_item->Rollback();
    494 
    495   EXPECT_TRUE(base::PathExists(file_name_from));
    496   EXPECT_TRUE(base::PathExists(file_name_to));
    497   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    498   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    499   // the backup file should be gone after rollback
    500   EXPECT_FALSE(base::PathExists(backup_file));
    501   EXPECT_FALSE(base::PathExists(alternate_to));
    502 }
    503 
    504 // Test overwrite option IF_NOT_PRESENT:
    505 // 1. If destination file/directory exist, the source should not be copied
    506 // 2. If destination file/directory do not exist, the source should be copied
    507 //    in the destination folder after Do() and should be rolled back after
    508 //    Rollback().
    509 // Flaky, http://crbug.com/59785.
    510 TEST_F(CopyTreeWorkItemTest, DISABLED_IfNotPresentTest) {
    511   // Create source file
    512   base::FilePath file_name_from(test_dir_.path());
    513   file_name_from = file_name_from.AppendASCII("File_From");
    514   CreateTextFile(file_name_from.value(), text_content_1);
    515   ASSERT_TRUE(base::PathExists(file_name_from));
    516 
    517   // Create an executable in destination path by copying ourself to it.
    518   wchar_t exe_full_path_str[MAX_PATH];
    519   ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
    520   base::FilePath exe_full_path(exe_full_path_str);
    521 
    522   base::FilePath dir_name_to(test_dir_.path());
    523   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    524   base::CreateDirectory(dir_name_to);
    525   ASSERT_TRUE(base::PathExists(dir_name_to));
    526   base::FilePath file_name_to(dir_name_to);
    527   file_name_to = file_name_to.AppendASCII("File_To");
    528   base::CopyFile(exe_full_path, file_name_to);
    529   ASSERT_TRUE(base::PathExists(file_name_to));
    530 
    531   // Get the path of backup file
    532   base::FilePath backup_file(temp_dir_.path());
    533   backup_file = backup_file.AppendASCII("File_To");
    534 
    535   // test Do().
    536   scoped_ptr<CopyTreeWorkItem> work_item(
    537       WorkItem::CreateCopyTreeWorkItem(
    538           file_name_from,
    539           file_name_to, temp_dir_.path(),
    540           WorkItem::IF_NOT_PRESENT,
    541           base::FilePath()));
    542   EXPECT_TRUE(work_item->Do());
    543 
    544   // verify that the source, destination have not changed and backup path
    545   // does not exist
    546   EXPECT_TRUE(base::PathExists(file_name_from));
    547   EXPECT_TRUE(base::PathExists(file_name_to));
    548   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    549   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    550   EXPECT_FALSE(base::PathExists(backup_file));
    551 
    552   // test rollback()
    553   work_item->Rollback();
    554 
    555   // verify that the source, destination have not changed and backup path
    556   // does not exist after rollback also
    557   EXPECT_TRUE(base::PathExists(file_name_from));
    558   EXPECT_TRUE(base::PathExists(file_name_to));
    559   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    560   EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
    561   EXPECT_FALSE(base::PathExists(backup_file));
    562 
    563   // Now delete the destination and try copying the file again.
    564   base::DeleteFile(file_name_to, true);
    565   work_item.reset(WorkItem::CreateCopyTreeWorkItem(
    566       file_name_from, file_name_to,
    567       temp_dir_.path(), WorkItem::IF_NOT_PRESENT,
    568       base::FilePath()));
    569   EXPECT_TRUE(work_item->Do());
    570 
    571   // verify that the source, destination are the same and backup path
    572   // does not exist
    573   EXPECT_TRUE(base::PathExists(file_name_from));
    574   EXPECT_TRUE(base::PathExists(file_name_to));
    575   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    576   EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    577   EXPECT_FALSE(base::PathExists(backup_file));
    578 
    579   // test rollback()
    580   work_item->Rollback();
    581 
    582   // verify that the destination does not exist anymore
    583   EXPECT_TRUE(base::PathExists(file_name_from));
    584   EXPECT_FALSE(base::PathExists(file_name_to));
    585   EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    586   EXPECT_FALSE(base::PathExists(backup_file));
    587 }
    588 
    589 // Copy one file without rollback. The existing one in destination is in use.
    590 // Verify it is moved to backup location and stays there.
    591 // Flaky, http://crbug.com/59783.
    592 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyFileInUseAndCleanup) {
    593   // Create source file
    594   base::FilePath file_name_from(test_dir_.path());
    595   file_name_from = file_name_from.AppendASCII("File_From");
    596   CreateTextFile(file_name_from.value(), text_content_1);
    597   ASSERT_TRUE(base::PathExists(file_name_from));
    598 
    599   // Create an executable in destination path by copying ourself to it.
    600   wchar_t exe_full_path_str[MAX_PATH];
    601   ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
    602   base::FilePath exe_full_path(exe_full_path_str);
    603 
    604   base::FilePath dir_name_to(test_dir_.path());
    605   dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
    606   base::CreateDirectory(dir_name_to);
    607   ASSERT_TRUE(base::PathExists(dir_name_to));
    608 
    609   base::FilePath file_name_to(dir_name_to);
    610   file_name_to = file_name_to.AppendASCII("File_To");
    611   base::CopyFile(exe_full_path, file_name_to);
    612   ASSERT_TRUE(base::PathExists(file_name_to));
    613 
    614   VLOG(1) << "copy ourself from " << exe_full_path.value()
    615           << " to " << file_name_to.value();
    616 
    617   // Run the executable in destination path
    618   STARTUPINFOW si = {sizeof(si)};
    619   PROCESS_INFORMATION pi = {0};
    620   ASSERT_TRUE(
    621       ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
    622                        NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
    623                        NULL, NULL, &si, &pi));
    624 
    625   base::FilePath backup_file;
    626 
    627   // test Do().
    628   {
    629     scoped_ptr<CopyTreeWorkItem> work_item(
    630         WorkItem::CreateCopyTreeWorkItem(file_name_from,
    631                                          file_name_to,
    632                                          temp_dir_.path(),
    633                                          WorkItem::IF_DIFFERENT,
    634                                          base::FilePath()));
    635 
    636     EXPECT_TRUE(work_item->Do());
    637 
    638     // Get the path of backup file
    639     backup_file = work_item->backup_path_.path();
    640     EXPECT_FALSE(backup_file.empty());
    641     backup_file = backup_file.AppendASCII("File_To");
    642 
    643     EXPECT_TRUE(base::PathExists(file_name_from));
    644     EXPECT_TRUE(base::PathExists(file_name_to));
    645     EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
    646     EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
    647     // verify the file in used is moved to backup place.
    648     EXPECT_TRUE(base::PathExists(backup_file));
    649     EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
    650   }
    651 
    652   // verify the file in used should be still at the backup place.
    653   EXPECT_TRUE(base::PathExists(backup_file));
    654   EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
    655 
    656   TerminateProcess(pi.hProcess, 0);
    657   // make sure the handle is closed.
    658   EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
    659   CloseHandle(pi.hProcess);
    660   CloseHandle(pi.hThread);
    661 }
    662 
    663 // Copy a tree from source to destination.
    664 // Flaky, http://crbug.com/59784.
    665 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyTree) {
    666   // Create source tree
    667   base::FilePath dir_name_from(test_dir_.path());
    668   dir_name_from = dir_name_from.AppendASCII("from");
    669   base::CreateDirectory(dir_name_from);
    670   ASSERT_TRUE(base::PathExists(dir_name_from));
    671 
    672   base::FilePath dir_name_from_1(dir_name_from);
    673   dir_name_from_1 = dir_name_from_1.AppendASCII("1");
    674   base::CreateDirectory(dir_name_from_1);
    675   ASSERT_TRUE(base::PathExists(dir_name_from_1));
    676 
    677   base::FilePath dir_name_from_2(dir_name_from);
    678   dir_name_from_2 = dir_name_from_2.AppendASCII("2");
    679   base::CreateDirectory(dir_name_from_2);
    680   ASSERT_TRUE(base::PathExists(dir_name_from_2));
    681 
    682   base::FilePath file_name_from_1(dir_name_from_1);
    683   file_name_from_1 = file_name_from_1.AppendASCII("File_1.txt");
    684   CreateTextFile(file_name_from_1.value(), text_content_1);
    685   ASSERT_TRUE(base::PathExists(file_name_from_1));
    686 
    687   base::FilePath file_name_from_2(dir_name_from_2);
    688   file_name_from_2 = file_name_from_2.AppendASCII("File_2.txt");
    689   CreateTextFile(file_name_from_2.value(), text_content_1);
    690   ASSERT_TRUE(base::PathExists(file_name_from_2));
    691 
    692   base::FilePath dir_name_to(test_dir_.path());
    693   dir_name_to = dir_name_to.AppendASCII("to");
    694 
    695   // test Do()
    696   {
    697     scoped_ptr<CopyTreeWorkItem> work_item(
    698         WorkItem::CreateCopyTreeWorkItem(dir_name_from,
    699                                          dir_name_to,
    700                                          temp_dir_.path(),
    701                                          WorkItem::ALWAYS,
    702                                          base::FilePath()));
    703 
    704     EXPECT_TRUE(work_item->Do());
    705   }
    706 
    707   base::FilePath file_name_to_1(dir_name_to);
    708   file_name_to_1 = file_name_to_1.AppendASCII("1");
    709   file_name_to_1 = file_name_to_1.AppendASCII("File_1.txt");
    710   EXPECT_TRUE(base::PathExists(file_name_to_1));
    711   VLOG(1) << "compare " << file_name_from_1.value()
    712           << " and " << file_name_to_1.value();
    713   EXPECT_TRUE(base::ContentsEqual(file_name_from_1, file_name_to_1));
    714 
    715   base::FilePath file_name_to_2(dir_name_to);
    716   file_name_to_2 = file_name_to_2.AppendASCII("2");
    717   file_name_to_2 = file_name_to_2.AppendASCII("File_2.txt");
    718   EXPECT_TRUE(base::PathExists(file_name_to_2));
    719   VLOG(1) << "compare " << file_name_from_2.value()
    720           << " and " << file_name_to_2.value();
    721   EXPECT_TRUE(base::ContentsEqual(file_name_from_2, file_name_to_2));
    722 }
    723