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.
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"
23 class CopyTreeWorkItemTest
: public testing::Test
{
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
) {
43 file
.open(filename
.c_str());
44 ASSERT_TRUE(file
.is_open());
49 bool IsFileInUse(const base::FilePath
& path
) {
50 if (!base::PathExists(path
))
53 HANDLE handle
= ::CreateFile(path
.value().c_str(), FILE_ALL_ACCESS
,
54 NULL
, NULL
, OPEN_EXISTING
, NULL
, NULL
);
55 if (handle
== INVALID_HANDLE_VALUE
)
62 // Simple function to read text from a file.
63 std::wstring
ReadTextFile(const std::wstring
& filename
) {
66 file
.open(filename
.c_str());
67 EXPECT_TRUE(file
.is_open());
68 file
.getline(contents
, 64);
70 return std::wstring(contents
);
73 const wchar_t text_content_1
[] = L
"Gooooooooooooooooooooogle";
74 const wchar_t text_content_2
[] = L
"Overwrite Me";
78 // Copy one file from source to destination.
79 TEST_F(CopyTreeWorkItemTest
, CopyFile
) {
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");
96 scoped_ptr
<CopyTreeWorkItem
> work_item(
97 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
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
));
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
,
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
));
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.
163 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
166 WorkItem::IF_DIFFERENT
,
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
));
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
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
,
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
228 EXPECT_TRUE(base::PathExists(backup_file
));
229 EXPECT_EQ(0, ReadTextFile(backup_file
.value()).compare(text_content_1
));
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.
243 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
246 WorkItem::IF_DIFFERENT
,
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
;
292 scoped_ptr
<CopyTreeWorkItem
> work_item(
293 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
296 WorkItem::IF_DIFFERENT
,
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};
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
));
356 scoped_ptr
<CopyTreeWorkItem
> work_item(
357 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
360 WorkItem::IF_DIFFERENT
,
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
));
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
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};
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
));
436 scoped_ptr
<CopyTreeWorkItem
> work_item(
437 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
440 WorkItem::NEW_NAME_IF_IN_USE
,
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
));
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
,
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
));
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
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");
538 scoped_ptr
<CopyTreeWorkItem
> work_item(
539 WorkItem::CreateCopyTreeWorkItem(
541 file_name_to
, temp_dir_
.path(),
542 WorkItem::IF_NOT_PRESENT
,
544 EXPECT_TRUE(work_item
->Do());
546 // verify that the source, destination have not changed and backup path
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
));
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
,
571 EXPECT_TRUE(work_item
->Do());
573 // verify that the source, destination are the same and backup path
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
));
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};
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
;
631 scoped_ptr
<CopyTreeWorkItem
> work_item(
632 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
635 WorkItem::IF_DIFFERENT
,
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");
699 scoped_ptr
<CopyTreeWorkItem
> work_item(
700 WorkItem::CreateCopyTreeWorkItem(dir_name_from
,
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
));