move_tree_work_item_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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/memory_mapped_file.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/path_service.h"
14#include "base/strings/string_util.h"
15#include "base/strings/utf_string_conversions.h"
16#include "chrome/installer/util/installer_util_test_common.h"
17#include "chrome/installer/util/move_tree_work_item.h"
18#include "chrome/installer/util/work_item.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21namespace {
22class MoveTreeWorkItemTest : public testing::Test {
23 protected:
24  virtual void SetUp() {
25    ASSERT_TRUE(temp_from_dir_.CreateUniqueTempDir());
26    ASSERT_TRUE(temp_to_dir_.CreateUniqueTempDir());
27  }
28
29  base::ScopedTempDir temp_from_dir_;
30  base::ScopedTempDir temp_to_dir_;
31};
32
33// Simple function to dump some text into a new file.
34void CreateTextFile(const std::wstring& filename,
35                    const std::wstring& contents) {
36  std::wofstream file;
37  file.open(base::UTF16ToASCII(filename).c_str());
38  ASSERT_TRUE(file.is_open());
39  file << contents;
40  file.close();
41}
42
43// Simple function to read text from a file.
44std::wstring ReadTextFile(const base::FilePath& path) {
45  WCHAR contents[64];
46  std::wifstream file;
47  file.open(base::UTF16ToASCII(path.value()).c_str());
48  EXPECT_TRUE(file.is_open());
49  file.getline(contents, arraysize(contents));
50  file.close();
51  return std::wstring(contents);
52}
53
54const wchar_t kTextContent1[] = L"Gooooooooooooooooooooogle";
55const wchar_t kTextContent2[] = L"Overwrite Me";
56};  // namespace
57
58// Move one directory from source to destination when destination does not
59// exist.
60TEST_F(MoveTreeWorkItemTest, MoveDirectory) {
61  // Create two level deep source dir
62  base::FilePath from_dir1(temp_from_dir_.path());
63  from_dir1 = from_dir1.AppendASCII("From_Dir1");
64  base::CreateDirectory(from_dir1);
65  ASSERT_TRUE(base::PathExists(from_dir1));
66
67  base::FilePath from_dir2(from_dir1);
68  from_dir2 = from_dir2.AppendASCII("From_Dir2");
69  base::CreateDirectory(from_dir2);
70  ASSERT_TRUE(base::PathExists(from_dir2));
71
72  base::FilePath from_file(from_dir2);
73  from_file = from_file.AppendASCII("From_File");
74  CreateTextFile(from_file.value(), kTextContent1);
75  ASSERT_TRUE(base::PathExists(from_file));
76
77  // Generate destination path
78  base::FilePath to_dir(temp_from_dir_.path());
79  to_dir = to_dir.AppendASCII("To_Dir");
80  ASSERT_FALSE(base::PathExists(to_dir));
81
82  base::FilePath to_file(to_dir);
83  to_file = to_file.AppendASCII("From_Dir2");
84  to_file = to_file.AppendASCII("From_File");
85  ASSERT_FALSE(base::PathExists(to_file));
86
87  // test Do()
88  scoped_ptr<MoveTreeWorkItem> work_item(
89      WorkItem::CreateMoveTreeWorkItem(from_dir1,
90                                       to_dir,
91                                       temp_to_dir_.path(),
92                                       WorkItem::ALWAYS_MOVE));
93  EXPECT_TRUE(work_item->Do());
94
95  EXPECT_FALSE(base::PathExists(from_dir1));
96  EXPECT_TRUE(base::PathExists(to_dir));
97  EXPECT_TRUE(base::PathExists(to_file));
98
99  // test rollback()
100  work_item->Rollback();
101
102  EXPECT_TRUE(base::PathExists(from_dir1));
103  EXPECT_TRUE(base::PathExists(from_file));
104  EXPECT_FALSE(base::PathExists(to_dir));
105}
106
107// Move one directory from source to destination when destination already
108// exists.
109TEST_F(MoveTreeWorkItemTest, MoveDirectoryDestExists) {
110  // Create two level deep source dir
111  base::FilePath from_dir1(temp_from_dir_.path());
112  from_dir1 = from_dir1.AppendASCII("From_Dir1");
113  base::CreateDirectory(from_dir1);
114  ASSERT_TRUE(base::PathExists(from_dir1));
115
116  base::FilePath from_dir2(from_dir1);
117  from_dir2 = from_dir2.AppendASCII("From_Dir2");
118  base::CreateDirectory(from_dir2);
119  ASSERT_TRUE(base::PathExists(from_dir2));
120
121  base::FilePath from_file(from_dir2);
122  from_file = from_file.AppendASCII("From_File");
123  CreateTextFile(from_file.value(), kTextContent1);
124  ASSERT_TRUE(base::PathExists(from_file));
125
126  // Create destination path
127  base::FilePath to_dir(temp_from_dir_.path());
128  to_dir = to_dir.AppendASCII("To_Dir");
129  base::CreateDirectory(to_dir);
130  ASSERT_TRUE(base::PathExists(to_dir));
131
132  base::FilePath orig_to_file(to_dir);
133  orig_to_file = orig_to_file.AppendASCII("To_File");
134  CreateTextFile(orig_to_file.value(), kTextContent2);
135  ASSERT_TRUE(base::PathExists(orig_to_file));
136
137  base::FilePath new_to_file(to_dir);
138  new_to_file = new_to_file.AppendASCII("From_Dir2");
139  new_to_file = new_to_file.AppendASCII("From_File");
140  ASSERT_FALSE(base::PathExists(new_to_file));
141
142  // test Do(), don't check for duplicates.
143  scoped_ptr<MoveTreeWorkItem> work_item(
144      WorkItem::CreateMoveTreeWorkItem(from_dir1,
145                                       to_dir,
146                                       temp_to_dir_.path(),
147                                       WorkItem::ALWAYS_MOVE));
148  EXPECT_TRUE(work_item->Do());
149
150  EXPECT_FALSE(base::PathExists(from_dir1));
151  EXPECT_TRUE(base::PathExists(to_dir));
152  EXPECT_TRUE(base::PathExists(new_to_file));
153  EXPECT_FALSE(base::PathExists(orig_to_file));
154
155  // test rollback()
156  work_item->Rollback();
157
158  EXPECT_TRUE(base::PathExists(from_dir1));
159  EXPECT_TRUE(base::PathExists(to_dir));
160  EXPECT_FALSE(base::PathExists(new_to_file));
161  EXPECT_TRUE(base::PathExists(orig_to_file));
162  EXPECT_EQ(0, ReadTextFile(orig_to_file).compare(kTextContent2));
163  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
164}
165
166// Move one file from source to destination when destination does not
167// exist.
168TEST_F(MoveTreeWorkItemTest, MoveAFile) {
169  // Create a file inside source dir
170  base::FilePath from_dir(temp_from_dir_.path());
171  from_dir = from_dir.AppendASCII("From_Dir");
172  base::CreateDirectory(from_dir);
173  ASSERT_TRUE(base::PathExists(from_dir));
174
175  base::FilePath from_file(from_dir);
176  from_file = from_file.AppendASCII("From_File");
177  CreateTextFile(from_file.value(), kTextContent1);
178  ASSERT_TRUE(base::PathExists(from_file));
179
180  // Generate destination file name
181  base::FilePath to_file(temp_from_dir_.path());
182  to_file = to_file.AppendASCII("To_File");
183  ASSERT_FALSE(base::PathExists(to_file));
184
185  // test Do()
186  scoped_ptr<MoveTreeWorkItem> work_item(
187      WorkItem::CreateMoveTreeWorkItem(from_file,
188                                       to_file,
189                                       temp_to_dir_.path(),
190                                       WorkItem::ALWAYS_MOVE));
191  EXPECT_TRUE(work_item->Do());
192
193  EXPECT_TRUE(base::PathExists(from_dir));
194  EXPECT_FALSE(base::PathExists(from_file));
195  EXPECT_TRUE(base::PathExists(to_file));
196  EXPECT_EQ(0, ReadTextFile(to_file).compare(kTextContent1));
197
198  // test rollback()
199  work_item->Rollback();
200
201  EXPECT_TRUE(base::PathExists(from_dir));
202  EXPECT_TRUE(base::PathExists(from_file));
203  EXPECT_FALSE(base::PathExists(to_file));
204  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
205}
206
207// Move one file from source to destination when destination already
208// exists.
209TEST_F(MoveTreeWorkItemTest, MoveFileDestExists) {
210  // Create a file inside source dir
211  base::FilePath from_dir(temp_from_dir_.path());
212  from_dir = from_dir.AppendASCII("From_Dir");
213  base::CreateDirectory(from_dir);
214  ASSERT_TRUE(base::PathExists(from_dir));
215
216  base::FilePath from_file(from_dir);
217  from_file = from_file.AppendASCII("From_File");
218  CreateTextFile(from_file.value(), kTextContent1);
219  ASSERT_TRUE(base::PathExists(from_file));
220
221  // Create destination path
222  base::FilePath to_dir(temp_from_dir_.path());
223  to_dir = to_dir.AppendASCII("To_Dir");
224  base::CreateDirectory(to_dir);
225  ASSERT_TRUE(base::PathExists(to_dir));
226
227  base::FilePath to_file(to_dir);
228  to_file = to_file.AppendASCII("To_File");
229  CreateTextFile(to_file.value(), kTextContent2);
230  ASSERT_TRUE(base::PathExists(to_file));
231
232  // test Do()
233  scoped_ptr<MoveTreeWorkItem> work_item(
234      WorkItem::CreateMoveTreeWorkItem(from_file,
235                                       to_dir,
236                                       temp_to_dir_.path(),
237                                       WorkItem::ALWAYS_MOVE));
238  EXPECT_TRUE(work_item->Do());
239
240  EXPECT_TRUE(base::PathExists(from_dir));
241  EXPECT_FALSE(base::PathExists(from_file));
242  EXPECT_TRUE(base::PathExists(to_dir));
243  EXPECT_FALSE(base::PathExists(to_file));
244  EXPECT_EQ(0, ReadTextFile(to_dir).compare(kTextContent1));
245
246  // test rollback()
247  work_item->Rollback();
248
249  EXPECT_TRUE(base::PathExists(from_dir));
250  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
251  EXPECT_TRUE(base::PathExists(to_dir));
252  EXPECT_EQ(0, ReadTextFile(to_file).compare(kTextContent2));
253}
254
255// Move one file from source to destination when destination already
256// exists and is in use.
257TEST_F(MoveTreeWorkItemTest, MoveFileDestInUse) {
258  // Create a file inside source dir
259  base::FilePath from_dir(temp_from_dir_.path());
260  from_dir = from_dir.AppendASCII("From_Dir");
261  base::CreateDirectory(from_dir);
262  ASSERT_TRUE(base::PathExists(from_dir));
263
264  base::FilePath from_file(from_dir);
265  from_file = from_file.AppendASCII("From_File");
266  CreateTextFile(from_file.value(), kTextContent1);
267  ASSERT_TRUE(base::PathExists(from_file));
268
269  // Create an executable in destination path by copying ourself to it.
270  base::FilePath to_dir(temp_from_dir_.path());
271  to_dir = to_dir.AppendASCII("To_Dir");
272  base::CreateDirectory(to_dir);
273  ASSERT_TRUE(base::PathExists(to_dir));
274
275  wchar_t exe_full_path_str[MAX_PATH];
276  ::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH);
277  base::FilePath exe_full_path(exe_full_path_str);
278  base::FilePath to_file(to_dir);
279  to_file = to_file.AppendASCII("To_File");
280  base::CopyFile(exe_full_path, to_file);
281  ASSERT_TRUE(base::PathExists(to_file));
282
283  // Run the executable in destination path
284  STARTUPINFOW si = {sizeof(si)};
285  PROCESS_INFORMATION pi = {0};
286  ASSERT_TRUE(::CreateProcess(NULL,
287                              const_cast<wchar_t*>(to_file.value().c_str()),
288                              NULL, NULL, FALSE,
289                              CREATE_NO_WINDOW | CREATE_SUSPENDED,
290                              NULL, NULL, &si, &pi));
291
292  // test Do()
293  scoped_ptr<MoveTreeWorkItem> work_item(
294      WorkItem::CreateMoveTreeWorkItem(from_file,
295                                       to_file,
296                                       temp_to_dir_.path(),
297                                       WorkItem::ALWAYS_MOVE));
298  EXPECT_TRUE(work_item->Do());
299
300  EXPECT_TRUE(base::PathExists(from_dir));
301  EXPECT_FALSE(base::PathExists(from_file));
302  EXPECT_TRUE(base::PathExists(to_dir));
303  EXPECT_EQ(0, ReadTextFile(to_file).compare(kTextContent1));
304
305  // test rollback()
306  work_item->Rollback();
307
308  EXPECT_TRUE(base::PathExists(from_dir));
309  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
310  EXPECT_TRUE(base::PathExists(to_dir));
311  EXPECT_TRUE(base::ContentsEqual(exe_full_path, to_file));
312
313  TerminateProcess(pi.hProcess, 0);
314  EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
315  CloseHandle(pi.hProcess);
316  CloseHandle(pi.hThread);
317}
318
319// Move one file that is in use to destination.
320TEST_F(MoveTreeWorkItemTest, MoveFileInUse) {
321  // Create an executable for source by copying ourself to a new source dir.
322  base::FilePath from_dir(temp_from_dir_.path());
323  from_dir = from_dir.AppendASCII("From_Dir");
324  base::CreateDirectory(from_dir);
325  ASSERT_TRUE(base::PathExists(from_dir));
326
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);
330  base::FilePath from_file(from_dir);
331  from_file = from_file.AppendASCII("From_File");
332  base::CopyFile(exe_full_path, from_file);
333  ASSERT_TRUE(base::PathExists(from_file));
334
335  // Create a destination source dir and generate destination file name.
336  base::FilePath to_dir(temp_from_dir_.path());
337  to_dir = to_dir.AppendASCII("To_Dir");
338  base::CreateDirectory(to_dir);
339  ASSERT_TRUE(base::PathExists(to_dir));
340
341  base::FilePath to_file(to_dir);
342  to_file = to_file.AppendASCII("To_File");
343  CreateTextFile(to_file.value(), kTextContent1);
344  ASSERT_TRUE(base::PathExists(to_file));
345
346  // Run the executable in source path
347  STARTUPINFOW si = {sizeof(si)};
348  PROCESS_INFORMATION pi = {0};
349  ASSERT_TRUE(::CreateProcess(NULL,
350                              const_cast<wchar_t*>(from_file.value().c_str()),
351                              NULL, NULL, FALSE,
352                              CREATE_NO_WINDOW | CREATE_SUSPENDED,
353                              NULL, NULL, &si, &pi));
354
355  // test Do()
356  scoped_ptr<MoveTreeWorkItem> work_item(
357      WorkItem::CreateMoveTreeWorkItem(from_file,
358                                       to_file,
359                                       temp_to_dir_.path(),
360                                       WorkItem::ALWAYS_MOVE));
361  EXPECT_TRUE(work_item->Do());
362
363  EXPECT_TRUE(base::PathExists(from_dir));
364  EXPECT_FALSE(base::PathExists(from_file));
365  EXPECT_TRUE(base::PathExists(to_dir));
366  EXPECT_TRUE(base::ContentsEqual(exe_full_path, to_file));
367
368  // Close the process and make sure all the conditions after Do() are
369  // still true.
370  TerminateProcess(pi.hProcess, 0);
371  EXPECT_TRUE(WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0);
372  CloseHandle(pi.hProcess);
373  CloseHandle(pi.hThread);
374
375  EXPECT_TRUE(base::PathExists(from_dir));
376  EXPECT_FALSE(base::PathExists(from_file));
377  EXPECT_TRUE(base::PathExists(to_dir));
378  EXPECT_TRUE(base::ContentsEqual(exe_full_path, to_file));
379
380  // test rollback()
381  work_item->Rollback();
382
383  EXPECT_TRUE(base::PathExists(from_dir));
384  EXPECT_TRUE(base::ContentsEqual(exe_full_path, from_file));
385  EXPECT_TRUE(base::PathExists(to_dir));
386  EXPECT_EQ(0, ReadTextFile(to_file).compare(kTextContent1));
387}
388
389// Move one directory from source to destination when destination already
390// exists.
391TEST_F(MoveTreeWorkItemTest, MoveDirectoryDestExistsCheckForDuplicatesFull) {
392  // Create two level deep source dir
393  base::FilePath from_dir1(temp_from_dir_.path());
394  from_dir1 = from_dir1.AppendASCII("From_Dir1");
395  base::CreateDirectory(from_dir1);
396  ASSERT_TRUE(base::PathExists(from_dir1));
397
398  base::FilePath from_dir2(from_dir1);
399  from_dir2 = from_dir2.AppendASCII("From_Dir2");
400  base::CreateDirectory(from_dir2);
401  ASSERT_TRUE(base::PathExists(from_dir2));
402
403  base::FilePath from_file(from_dir2);
404  from_file = from_file.AppendASCII("From_File");
405  CreateTextFile(from_file.value(), kTextContent1);
406  ASSERT_TRUE(base::PathExists(from_file));
407
408  // // Create a file hierarchy identical to the one in the source directory.
409  base::FilePath to_dir(temp_from_dir_.path());
410  to_dir = to_dir.AppendASCII("To_Dir");
411  ASSERT_TRUE(installer::test::CopyFileHierarchy(from_dir1, to_dir));
412
413  // Lock one of the files in the to destination directory to prevent moves.
414  base::FilePath orig_to_file(
415      to_dir.AppendASCII("From_Dir2").AppendASCII("From_File"));
416  base::MemoryMappedFile mapped_file;
417  EXPECT_TRUE(mapped_file.Initialize(orig_to_file));
418
419  // First check that we can't do the regular Move().
420  scoped_ptr<MoveTreeWorkItem> work_item(
421      WorkItem::CreateMoveTreeWorkItem(from_dir1,
422                                       to_dir,
423                                       temp_to_dir_.path(),
424                                       WorkItem::ALWAYS_MOVE));
425  EXPECT_FALSE(work_item->Do());
426  work_item->Rollback();
427
428  // Now test Do() with the check for duplicates. This should pass.
429  work_item.reset(
430      WorkItem::CreateMoveTreeWorkItem(from_dir1,
431                                       to_dir,
432                                       temp_to_dir_.path(),
433                                       WorkItem::CHECK_DUPLICATES));
434  EXPECT_TRUE(work_item->Do());
435
436  // Make sure that we "moved" the files, i.e. that the source directory isn't
437  // there anymore,
438  EXPECT_FALSE(base::PathExists(from_dir1));
439  // Make sure that the original directory structure and file are still present.
440  EXPECT_TRUE(base::PathExists(to_dir));
441  EXPECT_TRUE(base::PathExists(orig_to_file));
442  // Make sure that the backup path is not empty.
443  EXPECT_FALSE(base::IsDirectoryEmpty(temp_to_dir_.path()));
444
445  // Check that the work item believes the source to have been moved.
446  EXPECT_TRUE(work_item->source_moved_to_backup_);
447  EXPECT_FALSE(work_item->moved_to_dest_path_);
448  EXPECT_FALSE(work_item->moved_to_backup_);
449
450  // test rollback()
451  work_item->Rollback();
452
453  // Once we rollback all the original files should still be there, as should
454  // the source files.
455  EXPECT_TRUE(base::PathExists(from_dir1));
456  EXPECT_TRUE(base::PathExists(to_dir));
457  EXPECT_TRUE(base::PathExists(orig_to_file));
458  EXPECT_EQ(0, ReadTextFile(orig_to_file).compare(kTextContent1));
459  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
460}
461
462// Move one directory from source to destination when destination already
463// exists but contains only a subset of the files in source.
464TEST_F(MoveTreeWorkItemTest, MoveDirectoryDestExistsCheckForDuplicatesPartial) {
465  // Create two level deep source dir
466  base::FilePath from_dir1(temp_from_dir_.path());
467  from_dir1 = from_dir1.AppendASCII("From_Dir1");
468  base::CreateDirectory(from_dir1);
469  ASSERT_TRUE(base::PathExists(from_dir1));
470
471  base::FilePath from_dir2(from_dir1);
472  from_dir2 = from_dir2.AppendASCII("From_Dir2");
473  base::CreateDirectory(from_dir2);
474  ASSERT_TRUE(base::PathExists(from_dir2));
475
476  base::FilePath from_file(from_dir2);
477  from_file = from_file.AppendASCII("From_File");
478  CreateTextFile(from_file.value(), kTextContent1);
479  ASSERT_TRUE(base::PathExists(from_file));
480
481  base::FilePath from_file2(from_dir2);
482  from_file2 = from_file2.AppendASCII("From_File2");
483  CreateTextFile(from_file2.value(), kTextContent2);
484  ASSERT_TRUE(base::PathExists(from_file2));
485
486  // Create destination path
487  base::FilePath to_dir(temp_from_dir_.path());
488  to_dir = to_dir.AppendASCII("To_Dir");
489  base::CreateDirectory(to_dir);
490  ASSERT_TRUE(base::PathExists(to_dir));
491
492  // Create a sub-directory of the same name as in the source directory.
493  base::FilePath to_dir2(to_dir);
494  to_dir2 = to_dir2.AppendASCII("From_Dir2");
495  base::CreateDirectory(to_dir2);
496  ASSERT_TRUE(base::PathExists(to_dir2));
497
498  // Create one of the files in the to sub-directory, but not the other.
499  base::FilePath orig_to_file(to_dir2);
500  orig_to_file = orig_to_file.AppendASCII("From_File");
501  CreateTextFile(orig_to_file.value(), kTextContent1);
502  ASSERT_TRUE(base::PathExists(orig_to_file));
503
504  // test Do(), check for duplicates.
505  scoped_ptr<MoveTreeWorkItem> work_item(
506      WorkItem::CreateMoveTreeWorkItem(from_dir1,
507                                       to_dir,
508                                       temp_to_dir_.path(),
509                                       WorkItem::CHECK_DUPLICATES));
510  EXPECT_TRUE(work_item->Do());
511
512  // Make sure that we "moved" the files, i.e. that the source directory isn't
513  // there anymore,
514  EXPECT_FALSE(base::PathExists(from_dir1));
515  // Make sure that the original directory structure and file are still present.
516  EXPECT_TRUE(base::PathExists(to_dir));
517  EXPECT_TRUE(base::PathExists(orig_to_file));
518  // Make sure that the backup path is not empty.
519  EXPECT_FALSE(base::IsDirectoryEmpty(temp_to_dir_.path()));
520  // Make sure that the "new" file is also present.
521  base::FilePath new_to_file2(to_dir2);
522  new_to_file2 = new_to_file2.AppendASCII("From_File2");
523  EXPECT_TRUE(base::PathExists(new_to_file2));
524
525  // Check that the work item believes that this was a regular move.
526  EXPECT_FALSE(work_item->source_moved_to_backup_);
527  EXPECT_TRUE(work_item->moved_to_dest_path_);
528  EXPECT_TRUE(work_item->moved_to_backup_);
529
530  // test rollback()
531  work_item->Rollback();
532
533  // Once we rollback all the original files should still be there, as should
534  // the source files.
535  EXPECT_TRUE(base::PathExists(from_dir1));
536  EXPECT_TRUE(base::PathExists(to_dir));
537  EXPECT_TRUE(base::PathExists(orig_to_file));
538  EXPECT_EQ(0, ReadTextFile(orig_to_file).compare(kTextContent1));
539  EXPECT_EQ(0, ReadTextFile(from_file).compare(kTextContent1));
540
541  // Also, after rollback the new "to" file should be gone.
542  EXPECT_FALSE(base::PathExists(new_to_file2));
543}
544