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