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