Roll src/third_party/WebKit 116cf7f:79abaa8 (svn 189234:189235)
[chromium-blink-merge.git] / chrome / installer / util / copy_tree_work_item_unittest.cc
blob035696c8911e0106f2e4e77e51ea418f8a3b582e
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 virtual void SetUp() {
25 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
26 ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
29 virtual void TearDown() {
30 logging::CloseLogFile();
33 // the path to temporary directory used to contain the test operations
34 base::ScopedTempDir test_dir_;
35 base::ScopedTempDir temp_dir_;
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();
48 bool IsFileInUse(const base::FilePath& path) {
49 if (!base::PathExists(path))
50 return false;
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;
57 CloseHandle(handle);
58 return false;
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);
72 const wchar_t text_content_1[] = L"Gooooooooooooooooooooogle";
73 const wchar_t text_content_2[] = L"Overwrite Me";
75 } // namespace
77 // Copy one file from source to destination.
78 TEST_F(CopyTreeWorkItemTest, CopyFile) {
79 // Create source file
80 base::FilePath file_name_from(test_dir_.path());
81 file_name_from = file_name_from.AppendASCII("File_From.txt");
82 CreateTextFile(file_name_from.value(), text_content_1);
83 ASSERT_TRUE(base::PathExists(file_name_from));
85 // Create destination path
86 base::FilePath dir_name_to(test_dir_.path());
87 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
88 base::CreateDirectory(dir_name_to);
89 ASSERT_TRUE(base::PathExists(dir_name_to));
91 base::FilePath file_name_to(dir_name_to);
92 file_name_to = file_name_to.AppendASCII("File_To.txt");
94 // test Do()
95 scoped_ptr<CopyTreeWorkItem> work_item(
96 WorkItem::CreateCopyTreeWorkItem(file_name_from,
97 file_name_to,
98 temp_dir_.path(),
99 WorkItem::ALWAYS,
100 base::FilePath()));
102 EXPECT_TRUE(work_item->Do());
104 EXPECT_TRUE(base::PathExists(file_name_from));
105 EXPECT_TRUE(base::PathExists(file_name_to));
106 EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));
108 // test rollback()
109 work_item->Rollback();
111 EXPECT_FALSE(base::PathExists(file_name_to));
112 EXPECT_TRUE(base::PathExists(file_name_from));
115 // Copy one file, overwriting the existing one in destination.
116 // Test with always_overwrite being true or false. The file is overwritten
117 // regardless since the content at destination file is different from source.
118 TEST_F(CopyTreeWorkItemTest, CopyFileOverwrite) {
119 // Create source file
120 base::FilePath file_name_from(test_dir_.path());
121 file_name_from = file_name_from.AppendASCII("File_From.txt");
122 CreateTextFile(file_name_from.value(), text_content_1);
123 ASSERT_TRUE(base::PathExists(file_name_from));
125 // Create destination file
126 base::FilePath dir_name_to(test_dir_.path());
127 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
128 base::CreateDirectory(dir_name_to);
129 ASSERT_TRUE(base::PathExists(dir_name_to));
131 base::FilePath file_name_to(dir_name_to);
132 file_name_to = file_name_to.AppendASCII("File_To.txt");
133 CreateTextFile(file_name_to.value(), text_content_2);
134 ASSERT_TRUE(base::PathExists(file_name_to));
136 // test Do() with always_overwrite being true.
137 scoped_ptr<CopyTreeWorkItem> work_item(
138 WorkItem::CreateCopyTreeWorkItem(file_name_from,
139 file_name_to,
140 temp_dir_.path(),
141 WorkItem::ALWAYS,
142 base::FilePath()));
144 EXPECT_TRUE(work_item->Do());
146 EXPECT_TRUE(base::PathExists(file_name_from));
147 EXPECT_TRUE(base::PathExists(file_name_to));
148 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
149 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
151 // test rollback()
152 work_item->Rollback();
154 EXPECT_TRUE(base::PathExists(file_name_from));
155 EXPECT_TRUE(base::PathExists(file_name_to));
156 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
157 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));
159 // test Do() with always_overwrite being false.
160 // the file is still overwritten since the content is different.
161 work_item.reset(
162 WorkItem::CreateCopyTreeWorkItem(file_name_from,
163 file_name_to,
164 temp_dir_.path(),
165 WorkItem::IF_DIFFERENT,
166 base::FilePath()));
168 EXPECT_TRUE(work_item->Do());
170 EXPECT_TRUE(base::PathExists(file_name_from));
171 EXPECT_TRUE(base::PathExists(file_name_to));
172 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
173 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
175 // test rollback()
176 work_item->Rollback();
178 EXPECT_TRUE(base::PathExists(file_name_from));
179 EXPECT_TRUE(base::PathExists(file_name_to));
180 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
181 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_2));
184 // Copy one file, with the existing one in destination having the same
185 // content.
186 // If always_overwrite being true, the file is overwritten.
187 // If always_overwrite being false, the file is unchanged.
188 TEST_F(CopyTreeWorkItemTest, CopyFileSameContent) {
189 // Create source file
190 base::FilePath file_name_from(test_dir_.path());
191 file_name_from = file_name_from.AppendASCII("File_From.txt");
192 CreateTextFile(file_name_from.value(), text_content_1);
193 ASSERT_TRUE(base::PathExists(file_name_from));
195 // Create destination file
196 base::FilePath dir_name_to(test_dir_.path());
197 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
198 base::CreateDirectory(dir_name_to);
199 ASSERT_TRUE(base::PathExists(dir_name_to));
201 base::FilePath file_name_to(dir_name_to);
202 file_name_to = file_name_to.AppendASCII("File_To.txt");
203 CreateTextFile(file_name_to.value(), text_content_1);
204 ASSERT_TRUE(base::PathExists(file_name_to));
206 // test Do() with always_overwrite being true.
207 scoped_ptr<CopyTreeWorkItem> work_item(
208 WorkItem::CreateCopyTreeWorkItem(file_name_from,
209 file_name_to,
210 temp_dir_.path(),
211 WorkItem::ALWAYS,
212 base::FilePath()));
214 EXPECT_TRUE(work_item->Do());
216 // Get the path of backup file
217 base::FilePath backup_file(work_item->backup_path_.path());
218 EXPECT_FALSE(backup_file.empty());
219 backup_file = backup_file.AppendASCII("File_To.txt");
221 EXPECT_TRUE(base::PathExists(file_name_from));
222 EXPECT_TRUE(base::PathExists(file_name_to));
223 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
224 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
225 // we verify the file is overwritten by checking the existence of backup
226 // file.
227 EXPECT_TRUE(base::PathExists(backup_file));
228 EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_1));
230 // test rollback()
231 work_item->Rollback();
233 EXPECT_TRUE(base::PathExists(file_name_from));
234 EXPECT_TRUE(base::PathExists(file_name_to));
235 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
236 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
237 // the backup file should be gone after rollback
238 EXPECT_FALSE(base::PathExists(backup_file));
240 // test Do() with always_overwrite being false. nothing should change.
241 work_item.reset(
242 WorkItem::CreateCopyTreeWorkItem(file_name_from,
243 file_name_to,
244 temp_dir_.path(),
245 WorkItem::IF_DIFFERENT,
246 base::FilePath()));
248 EXPECT_TRUE(work_item->Do());
250 EXPECT_TRUE(base::PathExists(file_name_from));
251 EXPECT_TRUE(base::PathExists(file_name_to));
252 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
253 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
254 // we verify the file is not overwritten by checking that the backup
255 // file does not exist.
256 EXPECT_FALSE(base::PathExists(backup_file));
258 // test rollback(). nothing should happen here.
259 work_item->Rollback();
261 EXPECT_TRUE(base::PathExists(file_name_from));
262 EXPECT_TRUE(base::PathExists(file_name_to));
263 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
264 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
265 EXPECT_FALSE(base::PathExists(backup_file));
268 // Copy one file and without rollback. Verify all temporary files are deleted.
269 TEST_F(CopyTreeWorkItemTest, CopyFileAndCleanup) {
270 // Create source file
271 base::FilePath file_name_from(test_dir_.path());
272 file_name_from = file_name_from.AppendASCII("File_From.txt");
273 CreateTextFile(file_name_from.value(), text_content_1);
274 ASSERT_TRUE(base::PathExists(file_name_from));
276 // Create destination file
277 base::FilePath dir_name_to(test_dir_.path());
278 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
279 base::CreateDirectory(dir_name_to);
280 ASSERT_TRUE(base::PathExists(dir_name_to));
282 base::FilePath file_name_to(dir_name_to);
283 file_name_to = file_name_to.AppendASCII("File_To.txt");
284 CreateTextFile(file_name_to.value(), text_content_2);
285 ASSERT_TRUE(base::PathExists(file_name_to));
287 base::FilePath backup_file;
290 // test Do().
291 scoped_ptr<CopyTreeWorkItem> work_item(
292 WorkItem::CreateCopyTreeWorkItem(file_name_from,
293 file_name_to,
294 temp_dir_.path(),
295 WorkItem::IF_DIFFERENT,
296 base::FilePath()));
298 EXPECT_TRUE(work_item->Do());
300 // Get the path of backup file
301 backup_file = work_item->backup_path_.path();
302 EXPECT_FALSE(backup_file.empty());
303 backup_file = backup_file.AppendASCII("File_To.txt");
305 EXPECT_TRUE(base::PathExists(file_name_from));
306 EXPECT_TRUE(base::PathExists(file_name_to));
307 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
308 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
309 // verify the file is moved to backup place.
310 EXPECT_TRUE(base::PathExists(backup_file));
311 EXPECT_EQ(0, ReadTextFile(backup_file.value()).compare(text_content_2));
314 // verify the backup file is cleaned up as well.
315 EXPECT_FALSE(base::PathExists(backup_file));
318 // Copy one file, with the existing one in destination being used with
319 // overwrite option as IF_DIFFERENT. This destination-file-in-use should
320 // be moved to backup location after Do() and moved back after Rollback().
321 TEST_F(CopyTreeWorkItemTest, CopyFileInUse) {
322 // Create source file
323 base::FilePath file_name_from(test_dir_.path());
324 file_name_from = file_name_from.AppendASCII("File_From");
325 CreateTextFile(file_name_from.value(), text_content_1);
326 ASSERT_TRUE(base::PathExists(file_name_from));
328 // Create an executable in destination path by copying ourself to it.
329 wchar_t exe_full_path_str[MAX_PATH];
330 ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
331 base::FilePath exe_full_path(exe_full_path_str);
333 base::FilePath dir_name_to(test_dir_.path());
334 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
335 base::CreateDirectory(dir_name_to);
336 ASSERT_TRUE(base::PathExists(dir_name_to));
338 base::FilePath file_name_to(dir_name_to);
339 file_name_to = file_name_to.AppendASCII("File_To");
340 base::CopyFile(exe_full_path, file_name_to);
341 ASSERT_TRUE(base::PathExists(file_name_to));
343 VLOG(1) << "copy ourself from " << exe_full_path.value()
344 << " to " << file_name_to.value();
346 // Run the executable in destination path
347 STARTUPINFOW si = {sizeof(si)};
348 PROCESS_INFORMATION pi = {0};
349 ASSERT_TRUE(
350 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
351 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
352 NULL, NULL, &si, &pi));
354 // test Do().
355 scoped_ptr<CopyTreeWorkItem> work_item(
356 WorkItem::CreateCopyTreeWorkItem(file_name_from,
357 file_name_to,
358 temp_dir_.path(),
359 WorkItem::IF_DIFFERENT,
360 base::FilePath()));
362 EXPECT_TRUE(work_item->Do());
364 // Get the path of backup file
365 base::FilePath backup_file(work_item->backup_path_.path());
366 EXPECT_FALSE(backup_file.empty());
367 backup_file = backup_file.AppendASCII("File_To");
369 EXPECT_TRUE(base::PathExists(file_name_from));
370 EXPECT_TRUE(base::PathExists(file_name_to));
371 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
372 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
373 // verify the file in used is moved to backup place.
374 EXPECT_TRUE(base::PathExists(backup_file));
375 EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
377 // test rollback()
378 work_item->Rollback();
380 EXPECT_TRUE(base::PathExists(file_name_from));
381 EXPECT_TRUE(base::PathExists(file_name_to));
382 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
383 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
384 // the backup file should be gone after rollback
385 EXPECT_FALSE(base::PathExists(backup_file));
387 TerminateProcess(pi.hProcess, 0);
388 // make sure the handle is closed.
389 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
390 CloseHandle(pi.hProcess);
391 CloseHandle(pi.hThread);
394 // Test overwrite option NEW_NAME_IF_IN_USE:
395 // 1. If destination file is in use, the source should be copied with the
396 // new name after Do() and this new name file should be deleted
397 // after rollback.
398 // 2. If destination file is not in use, the source should be copied in the
399 // destination folder after Do() and should be rolled back after Rollback().
400 TEST_F(CopyTreeWorkItemTest, NewNameAndCopyTest) {
401 // Create source file
402 base::FilePath file_name_from(test_dir_.path());
403 file_name_from = file_name_from.AppendASCII("File_From");
404 CreateTextFile(file_name_from.value(), text_content_1);
405 ASSERT_TRUE(base::PathExists(file_name_from));
407 // Create an executable in destination path by copying ourself to it.
408 wchar_t exe_full_path_str[MAX_PATH];
409 ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
410 base::FilePath exe_full_path(exe_full_path_str);
412 base::FilePath dir_name_to(test_dir_.path());
413 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
414 base::CreateDirectory(dir_name_to);
415 ASSERT_TRUE(base::PathExists(dir_name_to));
417 base::FilePath file_name_to(dir_name_to), alternate_to(dir_name_to);
418 file_name_to = file_name_to.AppendASCII("File_To");
419 alternate_to = alternate_to.AppendASCII("Alternate_To");
420 base::CopyFile(exe_full_path, file_name_to);
421 ASSERT_TRUE(base::PathExists(file_name_to));
423 VLOG(1) << "copy ourself from " << exe_full_path.value()
424 << " to " << file_name_to.value();
426 // Run the executable in destination path
427 STARTUPINFOW si = {sizeof(si)};
428 PROCESS_INFORMATION pi = {0};
429 ASSERT_TRUE(
430 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
431 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
432 NULL, NULL, &si, &pi));
434 // test Do().
435 scoped_ptr<CopyTreeWorkItem> work_item(
436 WorkItem::CreateCopyTreeWorkItem(file_name_from,
437 file_name_to,
438 temp_dir_.path(),
439 WorkItem::NEW_NAME_IF_IN_USE,
440 alternate_to));
442 EXPECT_TRUE(work_item->Do());
444 EXPECT_TRUE(base::PathExists(file_name_from));
445 EXPECT_TRUE(base::PathExists(file_name_to));
446 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
447 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
448 // verify that the backup path does not exist
449 EXPECT_TRUE(work_item->backup_path_.path().empty());
450 EXPECT_TRUE(base::ContentsEqual(file_name_from, alternate_to));
452 // test rollback()
453 work_item->Rollback();
455 EXPECT_TRUE(base::PathExists(file_name_from));
456 EXPECT_TRUE(base::PathExists(file_name_to));
457 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
458 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
459 EXPECT_TRUE(work_item->backup_path_.path().empty());
460 // the alternate file should be gone after rollback
461 EXPECT_FALSE(base::PathExists(alternate_to));
463 TerminateProcess(pi.hProcess, 0);
464 // make sure the handle is closed.
465 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
466 CloseHandle(pi.hProcess);
467 CloseHandle(pi.hThread);
469 // Now the process has terminated, lets try overwriting the file again
470 work_item.reset(WorkItem::CreateCopyTreeWorkItem(
471 file_name_from, file_name_to,
472 temp_dir_.path(), WorkItem::NEW_NAME_IF_IN_USE,
473 alternate_to));
474 if (IsFileInUse(file_name_to))
475 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2));
476 // If file is still in use, the rest of the test will fail.
477 ASSERT_FALSE(IsFileInUse(file_name_to));
478 EXPECT_TRUE(work_item->Do());
480 // Get the path of backup file
481 base::FilePath backup_file(work_item->backup_path_.path());
482 EXPECT_FALSE(backup_file.empty());
483 backup_file = backup_file.AppendASCII("File_To");
485 EXPECT_TRUE(base::PathExists(file_name_from));
486 EXPECT_TRUE(base::PathExists(file_name_to));
487 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
488 EXPECT_TRUE(base::ContentsEqual(file_name_from, file_name_to));
489 // verify that the backup path does exist
490 EXPECT_TRUE(base::PathExists(backup_file));
491 EXPECT_FALSE(base::PathExists(alternate_to));
493 // test rollback()
494 work_item->Rollback();
496 EXPECT_TRUE(base::PathExists(file_name_from));
497 EXPECT_TRUE(base::PathExists(file_name_to));
498 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
499 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
500 // the backup file should be gone after rollback
501 EXPECT_FALSE(base::PathExists(backup_file));
502 EXPECT_FALSE(base::PathExists(alternate_to));
505 // Test overwrite option IF_NOT_PRESENT:
506 // 1. If destination file/directory exist, the source should not be copied
507 // 2. If destination file/directory do not exist, the source should be copied
508 // in the destination folder after Do() and should be rolled back after
509 // Rollback().
510 // Flaky, http://crbug.com/59785.
511 TEST_F(CopyTreeWorkItemTest, DISABLED_IfNotPresentTest) {
512 // Create source file
513 base::FilePath file_name_from(test_dir_.path());
514 file_name_from = file_name_from.AppendASCII("File_From");
515 CreateTextFile(file_name_from.value(), text_content_1);
516 ASSERT_TRUE(base::PathExists(file_name_from));
518 // Create an executable in destination path by copying ourself to it.
519 wchar_t exe_full_path_str[MAX_PATH];
520 ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
521 base::FilePath exe_full_path(exe_full_path_str);
523 base::FilePath dir_name_to(test_dir_.path());
524 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
525 base::CreateDirectory(dir_name_to);
526 ASSERT_TRUE(base::PathExists(dir_name_to));
527 base::FilePath file_name_to(dir_name_to);
528 file_name_to = file_name_to.AppendASCII("File_To");
529 base::CopyFile(exe_full_path, file_name_to);
530 ASSERT_TRUE(base::PathExists(file_name_to));
532 // Get the path of backup file
533 base::FilePath backup_file(temp_dir_.path());
534 backup_file = backup_file.AppendASCII("File_To");
536 // test Do().
537 scoped_ptr<CopyTreeWorkItem> work_item(
538 WorkItem::CreateCopyTreeWorkItem(
539 file_name_from,
540 file_name_to, temp_dir_.path(),
541 WorkItem::IF_NOT_PRESENT,
542 base::FilePath()));
543 EXPECT_TRUE(work_item->Do());
545 // verify that the source, destination have not changed and backup path
546 // does not exist
547 EXPECT_TRUE(base::PathExists(file_name_from));
548 EXPECT_TRUE(base::PathExists(file_name_to));
549 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
550 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
551 EXPECT_FALSE(base::PathExists(backup_file));
553 // test rollback()
554 work_item->Rollback();
556 // verify that the source, destination have not changed and backup path
557 // does not exist after rollback also
558 EXPECT_TRUE(base::PathExists(file_name_from));
559 EXPECT_TRUE(base::PathExists(file_name_to));
560 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
561 EXPECT_TRUE(base::ContentsEqual(exe_full_path, file_name_to));
562 EXPECT_FALSE(base::PathExists(backup_file));
564 // Now delete the destination and try copying the file again.
565 base::DeleteFile(file_name_to, true);
566 work_item.reset(WorkItem::CreateCopyTreeWorkItem(
567 file_name_from, file_name_to,
568 temp_dir_.path(), WorkItem::IF_NOT_PRESENT,
569 base::FilePath()));
570 EXPECT_TRUE(work_item->Do());
572 // verify that the source, destination are the same and backup path
573 // does not exist
574 EXPECT_TRUE(base::PathExists(file_name_from));
575 EXPECT_TRUE(base::PathExists(file_name_to));
576 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
577 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
578 EXPECT_FALSE(base::PathExists(backup_file));
580 // test rollback()
581 work_item->Rollback();
583 // verify that the destination does not exist anymore
584 EXPECT_TRUE(base::PathExists(file_name_from));
585 EXPECT_FALSE(base::PathExists(file_name_to));
586 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
587 EXPECT_FALSE(base::PathExists(backup_file));
590 // Copy one file without rollback. The existing one in destination is in use.
591 // Verify it is moved to backup location and stays there.
592 // Flaky, http://crbug.com/59783.
593 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyFileInUseAndCleanup) {
594 // Create source file
595 base::FilePath file_name_from(test_dir_.path());
596 file_name_from = file_name_from.AppendASCII("File_From");
597 CreateTextFile(file_name_from.value(), text_content_1);
598 ASSERT_TRUE(base::PathExists(file_name_from));
600 // Create an executable in destination path by copying ourself to it.
601 wchar_t exe_full_path_str[MAX_PATH];
602 ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
603 base::FilePath exe_full_path(exe_full_path_str);
605 base::FilePath dir_name_to(test_dir_.path());
606 dir_name_to = dir_name_to.AppendASCII("Copy_To_Subdir");
607 base::CreateDirectory(dir_name_to);
608 ASSERT_TRUE(base::PathExists(dir_name_to));
610 base::FilePath file_name_to(dir_name_to);
611 file_name_to = file_name_to.AppendASCII("File_To");
612 base::CopyFile(exe_full_path, file_name_to);
613 ASSERT_TRUE(base::PathExists(file_name_to));
615 VLOG(1) << "copy ourself from " << exe_full_path.value()
616 << " to " << file_name_to.value();
618 // Run the executable in destination path
619 STARTUPINFOW si = {sizeof(si)};
620 PROCESS_INFORMATION pi = {0};
621 ASSERT_TRUE(
622 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()),
623 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
624 NULL, NULL, &si, &pi));
626 base::FilePath backup_file;
628 // test Do().
630 scoped_ptr<CopyTreeWorkItem> work_item(
631 WorkItem::CreateCopyTreeWorkItem(file_name_from,
632 file_name_to,
633 temp_dir_.path(),
634 WorkItem::IF_DIFFERENT,
635 base::FilePath()));
637 EXPECT_TRUE(work_item->Do());
639 // Get the path of backup file
640 backup_file = work_item->backup_path_.path();
641 EXPECT_FALSE(backup_file.empty());
642 backup_file = backup_file.AppendASCII("File_To");
644 EXPECT_TRUE(base::PathExists(file_name_from));
645 EXPECT_TRUE(base::PathExists(file_name_to));
646 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1));
647 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1));
648 // verify the file in used is moved to backup place.
649 EXPECT_TRUE(base::PathExists(backup_file));
650 EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
653 // verify the file in used should be still at the backup place.
654 EXPECT_TRUE(base::PathExists(backup_file));
655 EXPECT_TRUE(base::ContentsEqual(exe_full_path, backup_file));
657 TerminateProcess(pi.hProcess, 0);
658 // make sure the handle is closed.
659 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
660 CloseHandle(pi.hProcess);
661 CloseHandle(pi.hThread);
664 // Copy a tree from source to destination.
665 // Flaky, http://crbug.com/59784.
666 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyTree) {
667 // Create source tree
668 base::FilePath dir_name_from(test_dir_.path());
669 dir_name_from = dir_name_from.AppendASCII("from");
670 base::CreateDirectory(dir_name_from);
671 ASSERT_TRUE(base::PathExists(dir_name_from));
673 base::FilePath dir_name_from_1(dir_name_from);
674 dir_name_from_1 = dir_name_from_1.AppendASCII("1");
675 base::CreateDirectory(dir_name_from_1);
676 ASSERT_TRUE(base::PathExists(dir_name_from_1));
678 base::FilePath dir_name_from_2(dir_name_from);
679 dir_name_from_2 = dir_name_from_2.AppendASCII("2");
680 base::CreateDirectory(dir_name_from_2);
681 ASSERT_TRUE(base::PathExists(dir_name_from_2));
683 base::FilePath file_name_from_1(dir_name_from_1);
684 file_name_from_1 = file_name_from_1.AppendASCII("File_1.txt");
685 CreateTextFile(file_name_from_1.value(), text_content_1);
686 ASSERT_TRUE(base::PathExists(file_name_from_1));
688 base::FilePath file_name_from_2(dir_name_from_2);
689 file_name_from_2 = file_name_from_2.AppendASCII("File_2.txt");
690 CreateTextFile(file_name_from_2.value(), text_content_1);
691 ASSERT_TRUE(base::PathExists(file_name_from_2));
693 base::FilePath dir_name_to(test_dir_.path());
694 dir_name_to = dir_name_to.AppendASCII("to");
696 // test Do()
698 scoped_ptr<CopyTreeWorkItem> work_item(
699 WorkItem::CreateCopyTreeWorkItem(dir_name_from,
700 dir_name_to,
701 temp_dir_.path(),
702 WorkItem::ALWAYS,
703 base::FilePath()));
705 EXPECT_TRUE(work_item->Do());
708 base::FilePath file_name_to_1(dir_name_to);
709 file_name_to_1 = file_name_to_1.AppendASCII("1");
710 file_name_to_1 = file_name_to_1.AppendASCII("File_1.txt");
711 EXPECT_TRUE(base::PathExists(file_name_to_1));
712 VLOG(1) << "compare " << file_name_from_1.value()
713 << " and " << file_name_to_1.value();
714 EXPECT_TRUE(base::ContentsEqual(file_name_from_1, file_name_to_1));
716 base::FilePath file_name_to_2(dir_name_to);
717 file_name_to_2 = file_name_to_2.AppendASCII("2");
718 file_name_to_2 = file_name_to_2.AppendASCII("File_2.txt");
719 EXPECT_TRUE(base::PathExists(file_name_to_2));
720 VLOG(1) << "compare " << file_name_from_2.value()
721 << " and " << file_name_to_2.value();
722 EXPECT_TRUE(base::ContentsEqual(file_name_from_2, file_name_to_2));