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/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"
22 class CopyTreeWorkItemTest
: public testing::Test
{
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
) {
40 file
.open(filename
.c_str());
41 ASSERT_TRUE(file
.is_open());
46 bool IsFileInUse(const base::FilePath
& path
) {
47 if (!base::PathExists(path
))
50 HANDLE handle
= ::CreateFile(path
.value().c_str(), FILE_ALL_ACCESS
,
51 NULL
, NULL
, OPEN_EXISTING
, NULL
, NULL
);
52 if (handle
== INVALID_HANDLE_VALUE
)
59 // Simple function to read text from a file.
60 std::wstring
ReadTextFile(const std::wstring
& filename
) {
63 file
.open(filename
.c_str());
64 EXPECT_TRUE(file
.is_open());
65 file
.getline(contents
, 64);
67 return std::wstring(contents
);
70 const wchar_t text_content_1
[] = L
"Gooooooooooooooooooooogle";
71 const wchar_t text_content_2
[] = L
"Overwrite Me";
75 // Copy one file from source to destination.
76 TEST_F(CopyTreeWorkItemTest
, CopyFile
) {
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");
93 scoped_ptr
<CopyTreeWorkItem
> work_item(
94 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
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
));
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
,
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
));
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.
160 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
163 WorkItem::IF_DIFFERENT
,
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
));
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
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
,
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
225 EXPECT_TRUE(base::PathExists(backup_file
));
226 EXPECT_EQ(0, ReadTextFile(backup_file
.value()).compare(text_content_1
));
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.
240 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
243 WorkItem::IF_DIFFERENT
,
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
;
289 scoped_ptr
<CopyTreeWorkItem
> work_item(
290 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
293 WorkItem::IF_DIFFERENT
,
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};
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
));
353 scoped_ptr
<CopyTreeWorkItem
> work_item(
354 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
357 WorkItem::IF_DIFFERENT
,
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
));
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
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};
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
));
433 scoped_ptr
<CopyTreeWorkItem
> work_item(
434 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
437 WorkItem::NEW_NAME_IF_IN_USE
,
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
));
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
,
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
));
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
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");
535 scoped_ptr
<CopyTreeWorkItem
> work_item(
536 WorkItem::CreateCopyTreeWorkItem(
538 file_name_to
, temp_dir_
.path(),
539 WorkItem::IF_NOT_PRESENT
,
541 EXPECT_TRUE(work_item
->Do());
543 // verify that the source, destination have not changed and backup path
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
));
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
,
568 EXPECT_TRUE(work_item
->Do());
570 // verify that the source, destination are the same and backup path
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
));
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};
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
;
628 scoped_ptr
<CopyTreeWorkItem
> work_item(
629 WorkItem::CreateCopyTreeWorkItem(file_name_from
,
632 WorkItem::IF_DIFFERENT
,
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");
696 scoped_ptr
<CopyTreeWorkItem
> work_item(
697 WorkItem::CreateCopyTreeWorkItem(dir_name_from
,
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
));