| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> | 5 #include <windows.h> |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 | 8 |
| 9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
| 14 #include "base/process_util.h" | 14 #include "base/process_util.h" |
| 15 #include "base/scoped_temp_dir.h" | 15 #include "base/scoped_temp_dir.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
| 18 #include "base/win/scoped_process_information.h" |
| 18 #include "chrome/installer/util/copy_tree_work_item.h" | 19 #include "chrome/installer/util/copy_tree_work_item.h" |
| 19 #include "chrome/installer/util/work_item.h" | 20 #include "chrome/installer/util/work_item.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 class CopyTreeWorkItemTest : public testing::Test { | 24 class CopyTreeWorkItemTest : public testing::Test { |
| 24 protected: | 25 protected: |
| 25 virtual void SetUp() { | 26 virtual void SetUp() { |
| 26 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 27 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 27 ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); | 28 ASSERT_TRUE(test_dir_.CreateUniqueTempDir()); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 FilePath file_name_to(dir_name_to); | 339 FilePath file_name_to(dir_name_to); |
| 339 file_name_to = file_name_to.AppendASCII("File_To"); | 340 file_name_to = file_name_to.AppendASCII("File_To"); |
| 340 file_util::CopyFile(exe_full_path, file_name_to); | 341 file_util::CopyFile(exe_full_path, file_name_to); |
| 341 ASSERT_TRUE(file_util::PathExists(file_name_to)); | 342 ASSERT_TRUE(file_util::PathExists(file_name_to)); |
| 342 | 343 |
| 343 VLOG(1) << "copy ourself from " << exe_full_path.value() | 344 VLOG(1) << "copy ourself from " << exe_full_path.value() |
| 344 << " to " << file_name_to.value(); | 345 << " to " << file_name_to.value(); |
| 345 | 346 |
| 346 // Run the executable in destination path | 347 // Run the executable in destination path |
| 347 STARTUPINFOW si = {sizeof(si)}; | 348 STARTUPINFOW si = {sizeof(si)}; |
| 348 PROCESS_INFORMATION pi = {0}; | 349 base::win::ScopedProcessInformation pi; |
| 349 ASSERT_TRUE( | 350 ASSERT_TRUE( |
| 350 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), | 351 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), |
| 351 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, | 352 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, |
| 352 NULL, NULL, &si, &pi)); | 353 NULL, NULL, &si, pi.Receive())); |
| 353 | 354 |
| 354 // test Do(). | 355 // test Do(). |
| 355 scoped_ptr<CopyTreeWorkItem> work_item( | 356 scoped_ptr<CopyTreeWorkItem> work_item( |
| 356 WorkItem::CreateCopyTreeWorkItem(file_name_from, | 357 WorkItem::CreateCopyTreeWorkItem(file_name_from, |
| 357 file_name_to, | 358 file_name_to, |
| 358 temp_dir_.path(), | 359 temp_dir_.path(), |
| 359 WorkItem::IF_DIFFERENT, | 360 WorkItem::IF_DIFFERENT, |
| 360 FilePath())); | 361 FilePath())); |
| 361 | 362 |
| 362 EXPECT_TRUE(work_item->Do()); | 363 EXPECT_TRUE(work_item->Do()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 377 // test rollback() | 378 // test rollback() |
| 378 work_item->Rollback(); | 379 work_item->Rollback(); |
| 379 | 380 |
| 380 EXPECT_TRUE(file_util::PathExists(file_name_from)); | 381 EXPECT_TRUE(file_util::PathExists(file_name_from)); |
| 381 EXPECT_TRUE(file_util::PathExists(file_name_to)); | 382 EXPECT_TRUE(file_util::PathExists(file_name_to)); |
| 382 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1)); | 383 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1)); |
| 383 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to)); | 384 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to)); |
| 384 // the backup file should be gone after rollback | 385 // the backup file should be gone after rollback |
| 385 EXPECT_FALSE(file_util::PathExists(backup_file)); | 386 EXPECT_FALSE(file_util::PathExists(backup_file)); |
| 386 | 387 |
| 387 TerminateProcess(pi.hProcess, 0); | 388 TerminateProcess(pi.Get().hProcess, 0); |
| 388 // make sure the handle is closed. | 389 EXPECT_TRUE(WaitForSingleObject(pi.Get().hProcess, 10000) == WAIT_OBJECT_0); |
| 389 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0); | |
| 390 CloseHandle(pi.hProcess); | |
| 391 CloseHandle(pi.hThread); | |
| 392 } | 390 } |
| 393 | 391 |
| 394 // Test overwrite option NEW_NAME_IF_IN_USE: | 392 // Test overwrite option NEW_NAME_IF_IN_USE: |
| 395 // 1. If destination file is in use, the source should be copied with the | 393 // 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 | 394 // new name after Do() and this new name file should be deleted |
| 397 // after rollback. | 395 // after rollback. |
| 398 // 2. If destination file is not in use, the source should be copied in the | 396 // 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(). | 397 // destination folder after Do() and should be rolled back after Rollback(). |
| 400 TEST_F(CopyTreeWorkItemTest, NewNameAndCopyTest) { | 398 TEST_F(CopyTreeWorkItemTest, NewNameAndCopyTest) { |
| 401 // Create source file | 399 // Create source file |
| (...skipping 16 matching lines...) Expand all Loading... |
| 418 file_name_to = file_name_to.AppendASCII("File_To"); | 416 file_name_to = file_name_to.AppendASCII("File_To"); |
| 419 alternate_to = alternate_to.AppendASCII("Alternate_To"); | 417 alternate_to = alternate_to.AppendASCII("Alternate_To"); |
| 420 file_util::CopyFile(exe_full_path, file_name_to); | 418 file_util::CopyFile(exe_full_path, file_name_to); |
| 421 ASSERT_TRUE(file_util::PathExists(file_name_to)); | 419 ASSERT_TRUE(file_util::PathExists(file_name_to)); |
| 422 | 420 |
| 423 VLOG(1) << "copy ourself from " << exe_full_path.value() | 421 VLOG(1) << "copy ourself from " << exe_full_path.value() |
| 424 << " to " << file_name_to.value(); | 422 << " to " << file_name_to.value(); |
| 425 | 423 |
| 426 // Run the executable in destination path | 424 // Run the executable in destination path |
| 427 STARTUPINFOW si = {sizeof(si)}; | 425 STARTUPINFOW si = {sizeof(si)}; |
| 428 PROCESS_INFORMATION pi = {0}; | 426 base::win::ScopedProcessInformation pi; |
| 429 ASSERT_TRUE( | 427 ASSERT_TRUE( |
| 430 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), | 428 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), |
| 431 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, | 429 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, |
| 432 NULL, NULL, &si, &pi)); | 430 NULL, NULL, &si, pi.Receive())); |
| 433 | 431 |
| 434 // test Do(). | 432 // test Do(). |
| 435 scoped_ptr<CopyTreeWorkItem> work_item( | 433 scoped_ptr<CopyTreeWorkItem> work_item( |
| 436 WorkItem::CreateCopyTreeWorkItem(file_name_from, | 434 WorkItem::CreateCopyTreeWorkItem(file_name_from, |
| 437 file_name_to, | 435 file_name_to, |
| 438 temp_dir_.path(), | 436 temp_dir_.path(), |
| 439 WorkItem::NEW_NAME_IF_IN_USE, | 437 WorkItem::NEW_NAME_IF_IN_USE, |
| 440 alternate_to)); | 438 alternate_to)); |
| 441 | 439 |
| 442 EXPECT_TRUE(work_item->Do()); | 440 EXPECT_TRUE(work_item->Do()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 453 work_item->Rollback(); | 451 work_item->Rollback(); |
| 454 | 452 |
| 455 EXPECT_TRUE(file_util::PathExists(file_name_from)); | 453 EXPECT_TRUE(file_util::PathExists(file_name_from)); |
| 456 EXPECT_TRUE(file_util::PathExists(file_name_to)); | 454 EXPECT_TRUE(file_util::PathExists(file_name_to)); |
| 457 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1)); | 455 EXPECT_EQ(0, ReadTextFile(file_name_from.value()).compare(text_content_1)); |
| 458 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to)); | 456 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to)); |
| 459 EXPECT_TRUE(work_item->backup_path_.path().empty()); | 457 EXPECT_TRUE(work_item->backup_path_.path().empty()); |
| 460 // the alternate file should be gone after rollback | 458 // the alternate file should be gone after rollback |
| 461 EXPECT_FALSE(file_util::PathExists(alternate_to)); | 459 EXPECT_FALSE(file_util::PathExists(alternate_to)); |
| 462 | 460 |
| 463 TerminateProcess(pi.hProcess, 0); | 461 TerminateProcess(pi.Get().hProcess, 0); |
| 464 // make sure the handle is closed. | 462 EXPECT_TRUE(WaitForSingleObject(pi.Get().hProcess, 10000) == WAIT_OBJECT_0); |
| 465 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0); | |
| 466 CloseHandle(pi.hProcess); | |
| 467 CloseHandle(pi.hThread); | |
| 468 | 463 |
| 469 // Now the process has terminated, lets try overwriting the file again | 464 // Now the process has terminated, lets try overwriting the file again |
| 470 work_item.reset(WorkItem::CreateCopyTreeWorkItem( | 465 work_item.reset(WorkItem::CreateCopyTreeWorkItem( |
| 471 file_name_from, file_name_to, | 466 file_name_from, file_name_to, |
| 472 temp_dir_.path(), WorkItem::NEW_NAME_IF_IN_USE, | 467 temp_dir_.path(), WorkItem::NEW_NAME_IF_IN_USE, |
| 473 alternate_to)); | 468 alternate_to)); |
| 474 if (IsFileInUse(file_name_to)) | 469 if (IsFileInUse(file_name_to)) |
| 475 base::PlatformThread::Sleep(2000); | 470 base::PlatformThread::Sleep(2000); |
| 476 // If file is still in use, the rest of the test will fail. | 471 // If file is still in use, the rest of the test will fail. |
| 477 ASSERT_FALSE(IsFileInUse(file_name_to)); | 472 ASSERT_FALSE(IsFileInUse(file_name_to)); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 FilePath file_name_to(dir_name_to); | 605 FilePath file_name_to(dir_name_to); |
| 611 file_name_to = file_name_to.AppendASCII("File_To"); | 606 file_name_to = file_name_to.AppendASCII("File_To"); |
| 612 file_util::CopyFile(exe_full_path, file_name_to); | 607 file_util::CopyFile(exe_full_path, file_name_to); |
| 613 ASSERT_TRUE(file_util::PathExists(file_name_to)); | 608 ASSERT_TRUE(file_util::PathExists(file_name_to)); |
| 614 | 609 |
| 615 VLOG(1) << "copy ourself from " << exe_full_path.value() | 610 VLOG(1) << "copy ourself from " << exe_full_path.value() |
| 616 << " to " << file_name_to.value(); | 611 << " to " << file_name_to.value(); |
| 617 | 612 |
| 618 // Run the executable in destination path | 613 // Run the executable in destination path |
| 619 STARTUPINFOW si = {sizeof(si)}; | 614 STARTUPINFOW si = {sizeof(si)}; |
| 620 PROCESS_INFORMATION pi = {0}; | 615 base::win::ScopedProcessInformation pi; |
| 621 ASSERT_TRUE( | 616 ASSERT_TRUE( |
| 622 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), | 617 ::CreateProcess(NULL, const_cast<wchar_t*>(file_name_to.value().c_str()), |
| 623 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, | 618 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED, |
| 624 NULL, NULL, &si, &pi)); | 619 NULL, NULL, &si, pi.Receive())); |
| 625 | 620 |
| 626 FilePath backup_file; | 621 FilePath backup_file; |
| 627 | 622 |
| 628 // test Do(). | 623 // test Do(). |
| 629 { | 624 { |
| 630 scoped_ptr<CopyTreeWorkItem> work_item( | 625 scoped_ptr<CopyTreeWorkItem> work_item( |
| 631 WorkItem::CreateCopyTreeWorkItem(file_name_from, | 626 WorkItem::CreateCopyTreeWorkItem(file_name_from, |
| 632 file_name_to, | 627 file_name_to, |
| 633 temp_dir_.path(), | 628 temp_dir_.path(), |
| 634 WorkItem::IF_DIFFERENT, | 629 WorkItem::IF_DIFFERENT, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 647 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1)); | 642 EXPECT_EQ(0, ReadTextFile(file_name_to.value()).compare(text_content_1)); |
| 648 // verify the file in used is moved to backup place. | 643 // verify the file in used is moved to backup place. |
| 649 EXPECT_TRUE(file_util::PathExists(backup_file)); | 644 EXPECT_TRUE(file_util::PathExists(backup_file)); |
| 650 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, backup_file)); | 645 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, backup_file)); |
| 651 } | 646 } |
| 652 | 647 |
| 653 // verify the file in used should be still at the backup place. | 648 // verify the file in used should be still at the backup place. |
| 654 EXPECT_TRUE(file_util::PathExists(backup_file)); | 649 EXPECT_TRUE(file_util::PathExists(backup_file)); |
| 655 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, backup_file)); | 650 EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, backup_file)); |
| 656 | 651 |
| 657 TerminateProcess(pi.hProcess, 0); | 652 TerminateProcess(pi.Get().hProcess, 0); |
| 658 // make sure the handle is closed. | 653 EXPECT_TRUE(WaitForSingleObject(pi.Get().hProcess, 10000) == WAIT_OBJECT_0); |
| 659 EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0); | |
| 660 CloseHandle(pi.hProcess); | |
| 661 CloseHandle(pi.hThread); | |
| 662 } | 654 } |
| 663 | 655 |
| 664 // Copy a tree from source to destination. | 656 // Copy a tree from source to destination. |
| 665 // Flaky, http://crbug.com/59784. | 657 // Flaky, http://crbug.com/59784. |
| 666 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyTree) { | 658 TEST_F(CopyTreeWorkItemTest, DISABLED_CopyTree) { |
| 667 // Create source tree | 659 // Create source tree |
| 668 FilePath dir_name_from(test_dir_.path()); | 660 FilePath dir_name_from(test_dir_.path()); |
| 669 dir_name_from = dir_name_from.AppendASCII("from"); | 661 dir_name_from = dir_name_from.AppendASCII("from"); |
| 670 file_util::CreateDirectory(dir_name_from); | 662 file_util::CreateDirectory(dir_name_from); |
| 671 ASSERT_TRUE(file_util::PathExists(dir_name_from)); | 663 ASSERT_TRUE(file_util::PathExists(dir_name_from)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 EXPECT_TRUE(file_util::ContentsEqual(file_name_from_1, file_name_to_1)); | 706 EXPECT_TRUE(file_util::ContentsEqual(file_name_from_1, file_name_to_1)); |
| 715 | 707 |
| 716 FilePath file_name_to_2(dir_name_to); | 708 FilePath file_name_to_2(dir_name_to); |
| 717 file_name_to_2 = file_name_to_2.AppendASCII("2"); | 709 file_name_to_2 = file_name_to_2.AppendASCII("2"); |
| 718 file_name_to_2 = file_name_to_2.AppendASCII("File_2.txt"); | 710 file_name_to_2 = file_name_to_2.AppendASCII("File_2.txt"); |
| 719 EXPECT_TRUE(file_util::PathExists(file_name_to_2)); | 711 EXPECT_TRUE(file_util::PathExists(file_name_to_2)); |
| 720 VLOG(1) << "compare " << file_name_from_2.value() | 712 VLOG(1) << "compare " << file_name_from_2.value() |
| 721 << " and " << file_name_to_2.value(); | 713 << " and " << file_name_to_2.value(); |
| 722 EXPECT_TRUE(file_util::ContentsEqual(file_name_from_2, file_name_to_2)); | 714 EXPECT_TRUE(file_util::ContentsEqual(file_name_from_2, file_name_to_2)); |
| 723 } | 715 } |
| OLD | NEW |