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