Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / installer / util / delete_tree_work_item_unittest.cc
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.
4
5 #include <windows.h>
6
7 #include <fstream>
8
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 "chrome/installer/util/delete_tree_work_item.h"
17 #include "chrome/installer/util/work_item.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace {
21
22 class DeleteTreeWorkItemTest : public testing::Test {
23  protected:
24   virtual void SetUp() {
25     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
26   }
27
28   // The temporary directory used to contain the test operations.
29   base::ScopedTempDir temp_dir_;
30 };
31
32 // Simple function to dump some text into a new file.
33 void CreateTextFile(const std::wstring& filename,
34                     const std::wstring& contents) {
35   std::ofstream file;
36   file.open(filename.c_str());
37   ASSERT_TRUE(file.is_open());
38   file << contents;
39   file.close();
40 }
41
42 const wchar_t text_content_1[] = L"delete me";
43
44 }  // namespace
45
46 // Delete a tree without key path. Everything should be deleted.
47 TEST_F(DeleteTreeWorkItemTest, DeleteTreeNoKeyPath) {
48   // Create tree to be deleted.
49   base::FilePath dir_name_delete(temp_dir_.path());
50   dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
51   base::CreateDirectory(dir_name_delete);
52   ASSERT_TRUE(base::PathExists(dir_name_delete));
53
54   base::FilePath dir_name_delete_1(dir_name_delete);
55   dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
56   base::CreateDirectory(dir_name_delete_1);
57   ASSERT_TRUE(base::PathExists(dir_name_delete_1));
58
59   base::FilePath dir_name_delete_2(dir_name_delete);
60   dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
61   base::CreateDirectory(dir_name_delete_2);
62   ASSERT_TRUE(base::PathExists(dir_name_delete_2));
63
64   base::FilePath file_name_delete_1(dir_name_delete_1);
65   file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
66   CreateTextFile(file_name_delete_1.value(), text_content_1);
67   ASSERT_TRUE(base::PathExists(file_name_delete_1));
68
69   base::FilePath file_name_delete_2(dir_name_delete_2);
70   file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
71   CreateTextFile(file_name_delete_2.value(), text_content_1);
72   ASSERT_TRUE(base::PathExists(file_name_delete_2));
73
74   // Test Do().
75   base::ScopedTempDir temp_dir;
76   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
77
78   std::vector<base::FilePath> key_files;
79   scoped_ptr<DeleteTreeWorkItem> work_item(
80       WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
81                                          key_files));
82   EXPECT_TRUE(work_item->Do());
83
84   // everything should be gone
85   EXPECT_FALSE(base::PathExists(file_name_delete_1));
86   EXPECT_FALSE(base::PathExists(file_name_delete_2));
87   EXPECT_FALSE(base::PathExists(dir_name_delete));
88
89   work_item->Rollback();
90   // everything should come back
91   EXPECT_TRUE(base::PathExists(file_name_delete_1));
92   EXPECT_TRUE(base::PathExists(file_name_delete_2));
93   EXPECT_TRUE(base::PathExists(dir_name_delete));
94 }
95
96
97 // Delete a tree with keypath but not in use. Everything should be gone.
98 // Rollback should bring back everything
99 TEST_F(DeleteTreeWorkItemTest, DeleteTree) {
100   // Create tree to be deleted
101   base::FilePath dir_name_delete(temp_dir_.path());
102   dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
103   base::CreateDirectory(dir_name_delete);
104   ASSERT_TRUE(base::PathExists(dir_name_delete));
105
106   base::FilePath dir_name_delete_1(dir_name_delete);
107   dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
108   base::CreateDirectory(dir_name_delete_1);
109   ASSERT_TRUE(base::PathExists(dir_name_delete_1));
110
111   base::FilePath dir_name_delete_2(dir_name_delete);
112   dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
113   base::CreateDirectory(dir_name_delete_2);
114   ASSERT_TRUE(base::PathExists(dir_name_delete_2));
115
116   base::FilePath file_name_delete_1(dir_name_delete_1);
117   file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
118   CreateTextFile(file_name_delete_1.value(), text_content_1);
119   ASSERT_TRUE(base::PathExists(file_name_delete_1));
120
121   base::FilePath file_name_delete_2(dir_name_delete_2);
122   file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
123   CreateTextFile(file_name_delete_2.value(), text_content_1);
124   ASSERT_TRUE(base::PathExists(file_name_delete_2));
125
126   // test Do()
127   base::ScopedTempDir temp_dir;
128   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
129
130   std::vector<base::FilePath> key_files(1, file_name_delete_1);
131   scoped_ptr<DeleteTreeWorkItem> work_item(
132       WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
133                                          key_files));
134   EXPECT_TRUE(work_item->Do());
135
136   // everything should be gone
137   EXPECT_FALSE(base::PathExists(file_name_delete_1));
138   EXPECT_FALSE(base::PathExists(file_name_delete_2));
139   EXPECT_FALSE(base::PathExists(dir_name_delete));
140
141   work_item->Rollback();
142   // everything should come back
143   EXPECT_TRUE(base::PathExists(file_name_delete_1));
144   EXPECT_TRUE(base::PathExists(file_name_delete_2));
145   EXPECT_TRUE(base::PathExists(dir_name_delete));
146 }
147
148 // Delete a tree with key_path in use. Everything should still be there.
149 TEST_F(DeleteTreeWorkItemTest, DeleteTreeInUse) {
150   // Create tree to be deleted
151   base::FilePath dir_name_delete(temp_dir_.path());
152   dir_name_delete = dir_name_delete.AppendASCII("to_be_delete");
153   base::CreateDirectory(dir_name_delete);
154   ASSERT_TRUE(base::PathExists(dir_name_delete));
155
156   base::FilePath dir_name_delete_1(dir_name_delete);
157   dir_name_delete_1 = dir_name_delete_1.AppendASCII("1");
158   base::CreateDirectory(dir_name_delete_1);
159   ASSERT_TRUE(base::PathExists(dir_name_delete_1));
160
161   base::FilePath dir_name_delete_2(dir_name_delete);
162   dir_name_delete_2 = dir_name_delete_2.AppendASCII("2");
163   base::CreateDirectory(dir_name_delete_2);
164   ASSERT_TRUE(base::PathExists(dir_name_delete_2));
165
166   base::FilePath file_name_delete_1(dir_name_delete_1);
167   file_name_delete_1 = file_name_delete_1.AppendASCII("File_1.txt");
168   CreateTextFile(file_name_delete_1.value(), text_content_1);
169   ASSERT_TRUE(base::PathExists(file_name_delete_1));
170
171   base::FilePath file_name_delete_2(dir_name_delete_2);
172   file_name_delete_2 = file_name_delete_2.AppendASCII("File_2.txt");
173   CreateTextFile(file_name_delete_2.value(), text_content_1);
174   ASSERT_TRUE(base::PathExists(file_name_delete_2));
175
176   // Create a key path file.
177   base::FilePath key_path(dir_name_delete);
178   key_path = key_path.AppendASCII("key_file.exe");
179
180   wchar_t exe_full_path_str[MAX_PATH];
181   ::GetModuleFileNameW(NULL, exe_full_path_str, MAX_PATH);
182   base::FilePath exe_full_path(exe_full_path_str);
183
184   base::CopyFile(exe_full_path, key_path);
185   ASSERT_TRUE(base::PathExists(key_path));
186
187   VLOG(1) << "copy ourself from " << exe_full_path.value()
188           << " to " << key_path.value();
189
190   // Run the key path file to keep it in use.
191   STARTUPINFOW si = {sizeof(si)};
192   PROCESS_INFORMATION pi = {0};
193   base::FilePath::StringType writable_key_path = key_path.value();
194   ASSERT_TRUE(
195       ::CreateProcessW(NULL, &writable_key_path[0],
196                        NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_SUSPENDED,
197                        NULL, NULL, &si, &pi));
198
199   // test Do().
200   {
201     base::ScopedTempDir temp_dir;
202     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
203
204     std::vector<base::FilePath> key_paths(1, key_path);
205     scoped_ptr<DeleteTreeWorkItem> work_item(
206         WorkItem::CreateDeleteTreeWorkItem(dir_name_delete, temp_dir.path(),
207                                            key_paths));
208
209     // delete should fail as file in use.
210     EXPECT_FALSE(work_item->Do());
211   }
212
213   // verify everything is still there.
214   EXPECT_TRUE(base::PathExists(key_path));
215   EXPECT_TRUE(base::PathExists(file_name_delete_1));
216   EXPECT_TRUE(base::PathExists(file_name_delete_2));
217
218   TerminateProcess(pi.hProcess, 0);
219   // make sure the handle is closed.
220   WaitForSingleObject(pi.hProcess, INFINITE);
221 }