Enable MSVC warning for unused locals.
[chromium-blink-merge.git] / chrome / installer / util / delete_tree_work_item_unittest.cc
blob75493fd5221beba76c22e8ea8624869ab930b4fc
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
3 // found in the LICENSE file.
5 #include <windows.h>
7 #include <fstream>
9 #include "base/base_paths.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string_util.h"
15 #include "chrome/installer/util/delete_tree_work_item.h"
16 #include "chrome/installer/util/work_item.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace {
21 class DeleteTreeWorkItemTest : public testing::Test {
22 protected:
23 virtual void SetUp() {
24 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
27 // The temporary directory used to contain the test operations.
28 base::ScopedTempDir temp_dir_;
31 // Simple function to dump some text into a new file.
32 void CreateTextFile(const std::wstring& filename,
33 const std::wstring& contents) {
34 std::ofstream file;
35 file.open(filename.c_str());
36 ASSERT_TRUE(file.is_open());
37 file << contents;
38 file.close();
41 const wchar_t text_content_1[] = L"delete me";
43 } // namespace
45 // Delete a tree without key path. Everything should be deleted.
46 TEST_F(DeleteTreeWorkItemTest, DeleteTreeNoKeyPath) {
47 // Create tree to be deleted.
48 base::FilePath dir_name_delete(temp_dir_.path());
49 dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
50 base::CreateDirectory(dir_name_delete);
51 ASSERT_TRUE(base::PathExists(dir_name_delete));
53 base::FilePath dir_name_delete_1(dir_name_delete);
54 dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
55 base::CreateDirectory(dir_name_delete_1);
56 ASSERT_TRUE(base::PathExists(dir_name_delete_1));
58 base::FilePath dir_name_delete_2(dir_name_delete);
59 dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
60 base::CreateDirectory(dir_name_delete_2);
61 ASSERT_TRUE(base::PathExists(dir_name_delete_2));
63 base::FilePath file_name_delete_1(dir_name_delete_1);
64 file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
65 CreateTextFile(file_name_delete_1.value(), text_content_1);
66 ASSERT_TRUE(base::PathExists(file_name_delete_1));
68 base::FilePath file_name_delete_2(dir_name_delete_2);
69 file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
70 CreateTextFile(file_name_delete_2.value(), text_content_1);
71 ASSERT_TRUE(base::PathExists(file_name_delete_2));
73 // Test Do().
74 base::ScopedTempDir temp_dir;
75 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
77 std::vector<base::FilePath> key_files;
78 scoped_ptr<DeleteTreeWorkItem> work_item(
79 WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
80 key_files));
81 EXPECT_TRUE(work_item->Do());
83 // everything should be gone
84 EXPECT_FALSE(base::PathExists(file_name_delete_1));
85 EXPECT_FALSE(base::PathExists(file_name_delete_2));
86 EXPECT_FALSE(base::PathExists(dir_name_delete));
88 work_item->Rollback();
89 // everything should come back
90 EXPECT_TRUE(base::PathExists(file_name_delete_1));
91 EXPECT_TRUE(base::PathExists(file_name_delete_2));
92 EXPECT_TRUE(base::PathExists(dir_name_delete));
96 // Delete a tree with keypath but not in use. Everything should be gone.
97 // Rollback should bring back everything
98 TEST_F(DeleteTreeWorkItemTest, DeleteTree) {
99 // Create tree to be deleted
100 base::FilePath dir_name_delete(temp_dir_.path());
101 dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
102 base::CreateDirectory(dir_name_delete);
103 ASSERT_TRUE(base::PathExists(dir_name_delete));
105 base::FilePath dir_name_delete_1(dir_name_delete);
106 dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
107 base::CreateDirectory(dir_name_delete_1);
108 ASSERT_TRUE(base::PathExists(dir_name_delete_1));
110 base::FilePath dir_name_delete_2(dir_name_delete);
111 dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
112 base::CreateDirectory(dir_name_delete_2);
113 ASSERT_TRUE(base::PathExists(dir_name_delete_2));
115 base::FilePath file_name_delete_1(dir_name_delete_1);
116 file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
117 CreateTextFile(file_name_delete_1.value(), text_content_1);
118 ASSERT_TRUE(base::PathExists(file_name_delete_1));
120 base::FilePath file_name_delete_2(dir_name_delete_2);
121 file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
122 CreateTextFile(file_name_delete_2.value(), text_content_1);
123 ASSERT_TRUE(base::PathExists(file_name_delete_2));
125 // test Do()
126 base::ScopedTempDir temp_dir;
127 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
129 std::vector<base::FilePath> key_files(1, file_name_delete_1);
130 scoped_ptr<DeleteTreeWorkItem> work_item(
131 WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
132 key_files));
133 EXPECT_TRUE(work_item->Do());
135 // everything should be gone
136 EXPECT_FALSE(base::PathExists(file_name_delete_1));
137 EXPECT_FALSE(base::PathExists(file_name_delete_2));
138 EXPECT_FALSE(base::PathExists(dir_name_delete));
140 work_item->Rollback();
141 // everything should come back
142 EXPECT_TRUE(base::PathExists(file_name_delete_1));
143 EXPECT_TRUE(base::PathExists(file_name_delete_2));
144 EXPECT_TRUE(base::PathExists(dir_name_delete));
147 // Delete a tree with key_path in use. Everything should still be there.
148 TEST_F(DeleteTreeWorkItemTest, DeleteTreeInUse) {
149 // Create tree to be deleted
150 base::FilePath dir_name_delete(temp_dir_.path());
151 dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
152 base::CreateDirectory(dir_name_delete);
153 ASSERT_TRUE(base::PathExists(dir_name_delete));
155 base::FilePath dir_name_delete_1(dir_name_delete);
156 dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
157 base::CreateDirectory(dir_name_delete_1);
158 ASSERT_TRUE(base::PathExists(dir_name_delete_1));
160 base::FilePath dir_name_delete_2(dir_name_delete);
161 dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
162 base::CreateDirectory(dir_name_delete_2);
163 ASSERT_TRUE(base::PathExists(dir_name_delete_2));
165 base::FilePath file_name_delete_1(dir_name_delete_1);
166 file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
167 CreateTextFile(file_name_delete_1.value(), text_content_1);
168 ASSERT_TRUE(base::PathExists(file_name_delete_1));
170 base::FilePath file_name_delete_2(dir_name_delete_2);
171 file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
172 CreateTextFile(file_name_delete_2.value(), text_content_1);
173 ASSERT_TRUE(base::PathExists(file_name_delete_2));
175 // Create a key path file.
176 base::FilePath key_path(dir_name_delete);
177 key_path = key_path.AppendASCII("key_file.exe");
179 wchar_t exe_full_path_str[MAX_PATH];
180 ::GetModuleFileNameW(NULL, exe_full_path_str, MAX_PATH);
181 base::FilePath exe_full_path(exe_full_path_str);
183 base::CopyFile(exe_full_path, key_path);
184 ASSERT_TRUE(base::PathExists(key_path));
186 VLOG(1) << "copy ourself from " << exe_full_path.value()
187 << " to " << key_path.value();
189 // Run the key path file to keep it in use.
190 STARTUPINFOW si = {sizeof(si)};
191 PROCESS_INFORMATION pi = {0};
192 base::FilePath::StringType writable_key_path = key_path.value();
193 ASSERT_TRUE(
194 ::CreateProcessW(NULL, &writable_key_path[0],
195 NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
196 NULL, NULL, &si, &pi));
198 // test Do().
200 base::ScopedTempDir temp_dir;
201 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
203 std::vector<base::FilePath> key_paths(1, key_path);
204 scoped_ptr<DeleteTreeWorkItem> work_item(
205 WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
206 key_paths));
208 // delete should fail as file in use.
209 EXPECT_FALSE(work_item->Do());
212 // verify everything is still there.
213 EXPECT_TRUE(base::PathExists(key_path));
214 EXPECT_TRUE(base::PathExists(file_name_delete_1));
215 EXPECT_TRUE(base::PathExists(file_name_delete_2));
217 TerminateProcess(pi.hProcess, 0);
218 // make sure the handle is closed.
219 WaitForSingleObject(pi.hProcess, INFINITE);