15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shellapi.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <tchar.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winioctl.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_POSIX)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <errno.h>
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <fcntl.h>
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <unistd.h>
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fstream>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <vector>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_paths.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.h"
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/test/test_file_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h"
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/win/windows_version.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/android/content_uri_utils.h"
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This macro helps avoid wrapped lines in the test structs.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FPL(x) FILE_PATH_LITERAL(x)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace base {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// To test that NormalizeFilePath() deals with NTFS reparse points correctly,
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// we need functions to create and delete reparse points.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _REPARSE_DATA_BUFFER {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ULONG  ReparseTag;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT  ReparseDataLength;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT  Reserved;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameOffset;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameLength;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameOffset;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameLength;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ULONG Flags;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WCHAR PathBuffer[1];
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } SymbolicLinkReparseBuffer;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameOffset;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameLength;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameOffset;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameLength;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WCHAR PathBuffer[1];
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } MountPointReparseBuffer;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UCHAR DataBuffer[1];
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } GenericReparseBuffer;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets a reparse point. |source| will now point to |target|. Returns true if
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the call succeeds, false otherwise.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetReparsePoint(HANDLE source, const FilePath& target_path) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring kPathPrefix = L"\\??\\";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring target_str;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The juction will not work if the target path does not start with \??\ .
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size()))
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_str += kPathPrefix;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_str += target_path.value();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* target = target_str.c_str();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[2000] = {0};
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD returned;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->ReparseTag = 0xa0000003;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->MountPointReparseBuffer.SubstituteNameLength = size_target;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->ReparseDataLength = size_target + 4 + 8;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_size = data->ReparseDataLength + 8;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NULL, 0, &returned, NULL)) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delete the reparse point referenced by |source|. Returns true if the call
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// succeeds, false otherwise.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteReparsePoint(HANDLE source) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD returned;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REPARSE_DATA_BUFFER data = {0};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.ReparseTag = 0xa0000003;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       &returned, NULL)) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Manages a reparse point for a test.
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class ReparsePoint {
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Creates a reparse point from |source| (an empty directory) to |target|.
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ReparsePoint(const FilePath& source, const FilePath& target) {
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    dir_.Set(
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ::CreateFile(source.value().c_str(),
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   FILE_ALL_ACCESS,
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   NULL,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   OPEN_EXISTING,
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   NULL));
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    created_ = dir_.IsValid() && SetReparsePoint(dir_.Get(), target);
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ~ReparsePoint() {
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (created_)
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DeleteReparsePoint(dir_.Get());
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool IsValid() { return created_; }
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  win::ScopedHandle dir_;
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool created_;
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ReparsePoint);
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provide a simple way to change the permissions bits on |path| in tests.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ASSERT failures will return, but not stop the test.  Caller should wrap
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls to this function in ASSERT_NO_FATAL_FAILURE().
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChangePosixFilePermissions(const FilePath& path,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int mode_bits_to_set,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int mode_bits_to_clear) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Can't set and clear the same bits.";
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mode = 0;
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(GetPosixFilePermissions(path, &mode));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode |= mode_bits_to_set;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode &= ~mode_bits_to_clear;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(SetPosixFilePermissions(path, mode));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t bogus_content[] = L"I'm cannon fodder.";
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int FILES_AND_DIRECTORIES =
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FileEnumerator::FILES | FileEnumerator::DIRECTORIES;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file_util winds up using autoreleased objects on the Mac, so this needs
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be a PlatformTest
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileUtilTest : public PlatformTest {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::SetUp();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScopedTempDir temp_dir_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Collects all the results from the given file enumerator, and provides an
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface to query whether a given file is present.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FindResultCollector {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit FindResultCollector(FileEnumerator& enumerator) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FilePath cur_file;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!(cur_file = enumerator.Next()).value().empty()) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FilePath::StringType path = cur_file.value();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The file should not be returned twice.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(files_.end() == files_.find(path))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "Same file returned twice";
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Save for later.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      files_.insert(path);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the enumerator found the file.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasFile(const FilePath& file) const {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return files_.find(file.value()) != files_.end();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size() {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<int>(files_.size());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<FilePath::StringType> files_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple function to dump some text into a new file.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateTextFile(const FilePath& filename,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::wstring& contents) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wofstream file;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.open(filename.value().c_str());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file.is_open());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file << contents;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.close();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple function to take out some text from a file.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring ReadTextFile(const FilePath& filename) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t contents[64];
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wifstream file;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.open(filename.value().c_str());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file.is_open());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.getline(contents, arraysize(contents));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.close();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::wstring(contents);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64 FileTimeAsUint64(const FILETIME& ft) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ULARGE_INTEGER u;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u.LowPart = ft.dwLowDateTime;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u.HighPart = ft.dwHighDateTime;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return u.QuadPart;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, FileAndDirectorySize) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should return 53 bytes.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_01 = temp_dir_.path().Append(FPL("The file 01.txt"));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_01, L"12345678901234567890");
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 size_f1 = 0;
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(GetFileSize(file_01, &size_f1));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20ll, size_f1);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path = temp_dir_.path().Append(FPL("Level2"));
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_02 = subdir_path.Append(FPL("The file 02.txt"));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_02, L"123456789012345678901234567890");
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 size_f2 = 0;
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(GetFileSize(file_02, &size_f2));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(30ll, size_f2);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subsubdir_path = subdir_path.Append(FPL("Level3"));
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subsubdir_path);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt"));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_03, L"123");
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 computed_size = ComputeDirectorySize(temp_dir_.path());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, NormalizeFilePathBasic) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory under the test dir.  Because we create it,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we know it is not a link.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_a_path = temp_dir_.path().Append(FPL("file_a"));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_path = temp_dir_.path().Append(FPL("dir"));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_b_path = dir_path.Append(FPL("file_b"));
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_path);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath normalized_file_a_path, normalized_file_b_path;
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(file_a_path));
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(NormalizeFilePath(file_a_path, &normalized_file_a_path))
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "NormalizeFilePath() should fail on nonexistent paths.";
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_a_path, bogus_content);
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_a_path));
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(NormalizeFilePath(file_a_path, &normalized_file_a_path));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_b_path, bogus_content);
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_b_path));
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(NormalizeFilePath(file_b_path, &normalized_file_b_path));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Beacuse this test created |dir_path|, we know it is not a link
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or junction.  So, the real path of the directory holding file a
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must be the parent of the path holding file b.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(normalized_file_a_path.DirName()
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .IsParent(normalized_file_b_path.DirName()));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, NormalizeFilePathReparsePoints) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the following directory structure:
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // temp_dir
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |-> base_a
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |   |-> sub_a
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |       |-> file.txt
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |       |-> long_name___... (Very long name.)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |           |-> sub_long
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |              |-> deep.txt
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |-> base_b
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     |-> to_sub_a (reparse point to temp_dir\base_a\sub_a)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     |-> to_base_b (reparse point to temp_dir\base_b)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     |-> to_sub_long (reparse point to temp_dir\sub_a\long_name_\sub_long)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath base_a = temp_dir_.path().Append(FPL("base_a"));
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(base_a));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath sub_a = base_a.Append(FPL("sub_a"));
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(sub_a));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_txt = sub_a.Append(FPL("file.txt"));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_txt, bogus_content);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Want a directory whose name is long enough to make the path to the file
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // inside just under MAX_PATH chars.  This will be used to test that when
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a junction expands to a path over MAX_PATH chars in length,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NormalizeFilePath() fails without crashing.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath sub_long_rel(FPL("sub_long"));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath deep_txt(FPL("deep.txt"));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int target_length = MAX_PATH;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_length -= (sub_a.value().length() + 1);  // +1 for the sepperator '\'.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_length -= (sub_long_rel.Append(deep_txt).value().length() + 1);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without making the path a bit shorter, CreateDirectory() fails.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the resulting path is still long enough to hit the failing case in
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NormalizePath().
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCreateDirLimit = 4;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_length -= kCreateDirLimit;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath::StringType long_name_str = FPL("long_name_");
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long_name_str.resize(target_length, '_');
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath long_name = sub_a.Append(FilePath(long_name_str));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath deep_file = long_name.Append(sub_long_rel).Append(deep_txt);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(MAX_PATH - kCreateDirLimit, deep_file.value().length());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath sub_long = deep_file.DirName();
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(sub_long));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(deep_file, bogus_content);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath base_b = temp_dir_.path().Append(FPL("base_b"));
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(base_b));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath to_sub_a = base_b.Append(FPL("to_sub_a"));
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(to_sub_a));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath normalized_path;
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReparsePoint reparse_to_sub_a(to_sub_a, sub_a);
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_TRUE(reparse_to_sub_a.IsValid());
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FilePath to_base_b = base_b.Append(FPL("to_base_b"));
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(CreateDirectory(to_base_b));
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReparsePoint reparse_to_base_b(to_base_b, base_b);
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_TRUE(reparse_to_base_b.IsValid());
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FilePath to_sub_long = base_b.Append(FPL("to_sub_long"));
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(CreateDirectory(to_sub_long));
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReparsePoint reparse_to_sub_long(to_sub_long, sub_long);
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_TRUE(reparse_to_sub_long.IsValid());
3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Normalize a junction free path: base_a\sub_a\file.txt .
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(NormalizeFilePath(file_txt, &normalized_path));
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Check that the path base_b\to_sub_a\file.txt can be normalized to exclude
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // the junction to_sub_a.
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                             &normalized_path));
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Check that the path base_b\to_base_b\to_base_b\to_sub_a\file.txt can be
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // normalized to exclude junctions to_base_b and to_sub_a .
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(NormalizeFilePath(base_b.Append(FPL("to_base_b"))
3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                   .Append(FPL("to_base_b"))
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                   .Append(FPL("to_sub_a"))
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                   .Append(FPL("file.txt")),
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                             &normalized_path));
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ASSERT_STREQ(file_txt.value().c_str(), normalized_path.value().c_str());
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // A long enough path will cause NormalizeFilePath() to fail.  Make a long
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // path using to_base_b many times, and check that paths long enough to fail
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // do not cause a crash.
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FilePath long_path = base_b;
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const int kLengthLimit = MAX_PATH + 200;
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    while (long_path.value().length() <= kLengthLimit) {
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      long_path = long_path.Append(FPL("to_base_b"));
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    long_path = long_path.Append(FPL("to_sub_a"))
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                         .Append(FPL("file.txt"));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_FALSE(NormalizeFilePath(long_path, &normalized_path));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Normalizing the junction to deep.txt should fail, because the expanded
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // path to deep.txt is longer than MAX_PATH.
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_FALSE(NormalizeFilePath(to_sub_long.Append(deep_txt),
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                              &normalized_path));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Delete the reparse points, and see that NormalizeFilePath() fails
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // to traverse them.
4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(NormalizeFilePath(to_sub_a.Append(FPL("file.txt")),
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            &normalized_path));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DevicePathToDriveLetter) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get a drive letter.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring real_drive_letter = temp_dir_.path().value().substr(0, 2);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!isalpha(real_drive_letter[0]) || ':' != real_drive_letter[1]) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Can't get a drive letter to test with.";
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the NT style path to that drive.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t device_path[MAX_PATH] = {'\0'};
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::QueryDosDevice(real_drive_letter.c_str(), device_path, MAX_PATH));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath actual_device_path(device_path);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath win32_path;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run DevicePathToDriveLetterPath() on the NT style path we got from
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // QueryDosDevice().  Expect the drive letter we started with.
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(DevicePathToDriveLetterPath(actual_device_path, &win32_path));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(real_drive_letter, win32_path.value());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add some directories to the path.  Expect those extra path componenets
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be preserved.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath kRelativePath(FPL("dir1\\dir2\\file.txt"));
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(DevicePathToDriveLetterPath(
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      actual_device_path.Append(kRelativePath),
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &win32_path));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FilePath(real_drive_letter + L"\\").Append(kRelativePath).value(),
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            win32_path.value());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deform the real path so that it is invalid by removing the last four
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // characters.  The way windows names devices that are hard disks
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (\Device\HardDiskVolume${NUMBER}) guarantees that the string is longer
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // than three characters.  The only way the truncated string could be a
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // real drive is if more than 10^3 disks are mounted:
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // \Device\HardDiskVolume10000 would be truncated to \Device\HardDiskVolume1
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that DevicePathToDriveLetterPath fails.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int path_length = actual_device_path.value().length();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_length = path_length - 4;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(0, new_length);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath prefix_of_real_device_path(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      actual_device_path.value().substr(0, new_length));
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(DevicePathToDriveLetterPath(prefix_of_real_device_path,
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                           &win32_path));
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(DevicePathToDriveLetterPath(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefix_of_real_device_path.Append(kRelativePath),
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &win32_path));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deform the real path so that it is invalid by adding some characters. For
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // example, if C: maps to \Device\HardDiskVolume8, then we simulate a
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request for the drive letter whose native path is
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // \Device\HardDiskVolume812345 .  We assume such a device does not exist,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because drives are numbered in order and mounting 112345 hard disks will
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // never happen.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FilePath::StringType kExtraChars = FPL("12345");
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath real_device_path_plus_numbers(
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      actual_device_path.value() + kExtraChars);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(DevicePathToDriveLetterPath(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      real_device_path_plus_numbers,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &win32_path));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(DevicePathToDriveLetterPath(
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      real_device_path_plus_numbers.Append(kRelativePath),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &win32_path));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileUtilTest, CreateTemporaryFileInDirLongPathTest) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test that CreateTemporaryFileInDir() creates a path and returns a long path
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if it is available. This test requires that:
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - the filesystem at |temp_dir_| supports long filenames.
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - the account has FILE_LIST_DIRECTORY permission for all ancestor
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   directories of |temp_dir_|.
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FilePath::CharType kLongDirName[] = FPL("A long path");
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FilePath::CharType kTestSubDirName[] = FPL("test");
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath long_test_dir = temp_dir_.path().Append(kLongDirName);
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(long_test_dir));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // kLongDirName is not a 8.3 component. So GetShortName() should give us a
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // different short name.
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WCHAR path_buffer[MAX_PATH];
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DWORD path_buffer_length = GetShortPathName(long_test_dir.value().c_str(),
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              path_buffer, MAX_PATH);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_LT(path_buffer_length, DWORD(MAX_PATH));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NE(DWORD(0), path_buffer_length);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath short_test_dir(path_buffer);
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_STRNE(kLongDirName, short_test_dir.BaseName().value().c_str());
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath temp_file;
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateTemporaryFileInDir(short_test_dir, &temp_file));
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_STREQ(kLongDirName, temp_file.DirName().BaseName().value().c_str());
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(temp_file));
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a subdirectory of |long_test_dir| and make |long_test_dir|
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unreadable. We should still be able to create a temp file in the
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // subdirectory, but we won't be able to determine the long path for it. This
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // mimics the environment that some users run where their user profiles reside
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in a location where the don't have full access to the higher level
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // directories. (Note that this assumption is true for NTFS, but not for some
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // network file systems. E.g. AFS).
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath access_test_dir = long_test_dir.Append(kTestSubDirName);
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(access_test_dir));
5316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::FilePermissionRestorer long_test_dir_restorer(long_test_dir);
5326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(base::MakeFileUnreadable(long_test_dir));
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use the short form of the directory to create a temporary filename.
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateTemporaryFileInDir(
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      short_test_dir.Append(kTestSubDirName), &temp_file));
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(temp_file));
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(short_test_dir.IsParent(temp_file.DirName()));
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that the long path can't be determined for |temp_file|.
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path_buffer_length = GetLongPathName(temp_file.value().c_str(),
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       path_buffer, MAX_PATH);
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DWORD(0), path_buffer_length);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateAndReadSymlinks) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath link_from = temp_dir_.path().Append(FPL("from_file"));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath link_to = temp_dir_.path().Append(FPL("to_file"));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(link_to, bogus_content);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create file symlink.";
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // If we created the link properly, we should be able to read the contents
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // through it.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring contents = ReadTextFile(link_from);
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(bogus_content, contents);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath result;
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(ReadSymbolicLink(link_from, &result));
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(link_to.value(), result.value());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Link to a directory.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_from = temp_dir_.path().Append(FPL("from_dir"));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_to = temp_dir_.path().Append(FPL("to_dir"));
570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(link_to));
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create directory symlink.";
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test failures.
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(CreateSymbolicLink(link_to, link_to));
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(ReadSymbolicLink(link_to, &result));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath missing = temp_dir_.path().Append(FPL("missing"));
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(ReadSymbolicLink(missing, &result));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following test of NormalizeFilePath() require that we create a symlink.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This can not be done on Windows before Vista.  On Vista, creating a symlink
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requires privilege "SeCreateSymbolicLinkPrivilege".
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(skerner): Investigate the possibility of giving base_unittests the
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// privileges required to create a symlink.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, NormalizeFilePathSymlinks) {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Link one file to another.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath link_from = temp_dir_.path().Append(FPL("from_file"));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath link_to = temp_dir_.path().Append(FPL("to_file"));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(link_to, bogus_content);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create file symlink.";
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that NormalizeFilePath sees the link.
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FilePath normalized_path;
597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(NormalizeFilePath(link_from, &normalized_path));
598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_NE(link_from, link_to);
599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(link_to.BaseName().value(), normalized_path.BaseName().value());
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Link to a directory.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_from = temp_dir_.path().Append(FPL("from_dir"));
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_to = temp_dir_.path().Append(FPL("to_dir"));
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(link_to));
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create directory symlink.";
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path))
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Links to directories should return false.";
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that a loop in the links causes NormalizeFilePath() to return false.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_from = temp_dir_.path().Append(FPL("link_a"));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  link_to = temp_dir_.path().Append(FPL("link_b"));
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_to, link_from))
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create loop symlink a.";
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(link_from, link_to))
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create loop symlink b.";
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Infinite loop!
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(NormalizeFilePath(link_from, &normalized_path));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteNonExistent) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath non_existent = temp_dir_.path().AppendASCII("bogus_file_dne.foobar");
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(non_existent, false));
630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(non_existent, true));
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileUtilTest, DeleteNonExistentWithNonExistentParent) {
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FilePath non_existent = temp_dir_.path().AppendASCII("bogus_topdir");
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  non_existent = non_existent.AppendASCII("bogus_subdir");
638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(DeleteFile(non_existent, false));
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(DeleteFile(non_existent, true));
643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(PathExists(non_existent));
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteFile) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 1.txt"));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure it's deleted
653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_name, false));
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test recursive case, create a new file
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure it's deleted
662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_name, true));
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteSymlinkToExistentFile) {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteFile 2.txt"));
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a symlink to the file.
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_link = temp_dir_.path().Append("file_link_2");
675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(file_name, file_link))
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Failed to create symlink.";
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the symbolic link.
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_link, false));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure original file is not deleted.
682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_link));
683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name));
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteSymlinkToNonExistentFile) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a non-existent file path.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath non_existent = temp_dir_.path().Append(FPL("Test DeleteFile 3.txt"));
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(non_existent));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a symlink to the non-existent file.
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_link = temp_dir_.path().Append("file_link_3");
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(non_existent, file_link))
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Failed to create symlink.";
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the symbolic link is exist.
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(IsLink(file_link));
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_link));
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the symbolic link.
701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_link, false));
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the symbolic link is deleted.
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(IsLink(file_link));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, ChangeFilePermissionsAndRead) {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file path.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kData("hello");
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int buffer_size = kData.length();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* buffer = new char[buffer_size];
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write file.
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(kData.length()),
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            WriteFile(file_name, kData.data(), kData.length()));
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name));
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file is readable.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 mode = 0;
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of the read permission.
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(mode & FILE_PERMISSION_READ_BY_USER);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file can't be read.
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(-1, ReadFile(file_name, buffer, buffer_size));
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give the read permission.
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(file_name, FILE_PERMISSION_READ_BY_USER));
736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(mode & FILE_PERMISSION_READ_BY_USER);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file can be read.
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(kData.length()),
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            ReadFile(file_name, buffer, buffer_size));
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the file.
743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_name, false));
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete[] buffer;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, ChangeFilePermissionsAndWrite) {
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file path.
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("Test Readable File.txt"));
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kData("hello");
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write file.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(kData.length()),
758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            WriteFile(file_name, kData.data(), kData.length()));
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name));
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file is writable.
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mode = 0;
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(PathIsWritable(file_name));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of the write permission.
768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(file_name, 0u));
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(mode & FILE_PERMISSION_WRITE_BY_USER);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file can't be write.
772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(-1, WriteFile(file_name, kData.data(), kData.length()));
7737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(PathIsWritable(file_name));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give read permission.
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(file_name,
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      FILE_PERMISSION_WRITE_BY_USER));
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(file_name, &mode));
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(mode & FILE_PERMISSION_WRITE_BY_USER);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file can be write.
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(kData.length()),
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            WriteFile(file_name, kData.data(), kData.length()));
7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(PathIsWritable(file_name));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the file.
786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(file_name, false));
787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, ChangeDirectoryPermissionsAndEnumerate) {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory path.
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path =
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FPL("PermissionTest1"));
794a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path);
795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path));
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a dummy file to enumerate.
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = subdir_path.Append(FPL("Test Readable File.txt"));
799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kData("hello");
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(kData.length()),
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            WriteFile(file_name, kData.data(), kData.length()));
803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the directory has the all permissions.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mode = 0;
807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of the permissions from the directory.
811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(subdir_path, 0u));
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(mode & FILE_PERMISSION_USER_MASK);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file in the directory can't be enumerated.
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f1(subdir_path, true, FileEnumerator::FILES);
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_path));
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c1(f1);
819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(0, c1.size());
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(GetPosixFilePermissions(file_name, &mode));
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give the permissions to the directory.
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(subdir_path, FILE_PERMISSION_USER_MASK));
824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(subdir_path, &mode));
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(FILE_PERMISSION_USER_MASK, mode & FILE_PERMISSION_USER_MASK);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the file in the directory can be enumerated.
828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f2(subdir_path, true, FileEnumerator::FILES);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c2(f2);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2.HasFile(file_name));
831010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(1, c2.size());
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the file.
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(subdir_path, true));
835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_path));
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the Delete function works for wild cards, especially
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the recursion flag.  Also coincidentally tests PathExists.
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(erikkay): see if anyone's actually using this feature of the API
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteWildCard) {
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file and a directory
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("Test DeleteWildCard.txt"));
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path = temp_dir_.path().Append(FPL("DeleteWildCardDir"));
851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path);
852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path));
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the wildcard path
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath directory_contents = temp_dir_.path();
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  directory_contents = directory_contents.Append(FPL("*"));
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete non-recursively and check that only the file is deleted
859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(directory_contents, false));
860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_path));
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete recursively and make sure all contents are deleted
864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(directory_contents, true));
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_path));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(erikkay): see if anyone's actually using this feature of the API
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteNonExistantWildCard) {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file and a directory
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path =
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FPL("DeleteNonExistantWildCard"));
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path);
875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path));
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the wildcard path
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath directory_contents = subdir_path;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  directory_contents = directory_contents.Append(FPL("*"));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete non-recursively and check nothing got deleted
882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(directory_contents, false));
883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_path));
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete recursively and check nothing got deleted
886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(directory_contents, true));
887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_path));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests non-recursive Delete() for a directory.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteDirNonRecursive) {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory and put a file and two directories inside.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirNonRecursive"));
895a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(test_subdir);
896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(test_subdir));
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = test_subdir.Append(FPL("Test DeleteDir.txt"));
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path1);
904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path1));
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
907a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path2);
908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path2));
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete non-recursively and check that the empty dir got deleted
911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(subdir_path2, false));
912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_path2));
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete non-recursively and check that nothing got deleted
915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(DeleteFile(test_subdir, false));
916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(test_subdir));
917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name));
918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_path1));
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests recursive Delete() for a directory.
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DeleteDirRecursive) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory and put a file and two directories inside.
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_subdir = temp_dir_.path().Append(FPL("DeleteDirRecursive"));
925a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(test_subdir);
926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(test_subdir));
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name = test_subdir.Append(FPL("Test DeleteDirRecursive.txt"));
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name, bogus_content);
930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name));
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path1 = test_subdir.Append(FPL("TestSubDir1"));
933a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path1);
934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path1));
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_path2 = test_subdir.Append(FPL("TestSubDir2"));
937a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_path2);
938f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_path2));
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete recursively and check that the empty dir got deleted
941f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(subdir_path2, true));
942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_path2));
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete recursively and check that everything got deleted
945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(test_subdir, true));
946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name));
947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_path1));
948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_subdir));
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, MoveFileNew) {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination.
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to = temp_dir_.path().Append(
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(file_name_to));
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(Move(file_name_from, file_name_to));
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been moved.
966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, MoveFileExists) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination name.
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to = temp_dir_.path().Append(
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE_PATH_LITERAL("Move_Test_File_Destination.txt"));
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_to, L"Old file content");
981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_to));
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(Move(file_name_from, file_name_to));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been moved.
986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, MoveFileDirExists) {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
996f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination directory
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_to);
1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_to));
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(Move(file_name_from, dir_name_to));
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, MoveNew) {
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1012a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath txt_file_name(FILE_PATH_LITERAL("Move_Test_File.txt"));
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath file_name_from = dir_name_from.Append(txt_file_name);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the directory.
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_To_Subdir"));
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(dir_name_to));
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(Move(dir_name_from, dir_name_to));
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been moved.
1032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(dir_name_from));
1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1035f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test path traversal.
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_name_from = dir_name_to.Append(txt_file_name);
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_name_to = dir_name_to.Append(FILE_PATH_LITERAL(".."));
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_name_to = file_name_to.Append(txt_file_name);
1041f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(Move(file_name_from, file_name_to));
1042f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_to));
1044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(internal::MoveUnsafe(file_name_from, file_name_to));
1045f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
1046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, MoveExist) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Move_From_Subdir"));
1053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1060f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the directory
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_exists =
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_exists.Append(FILE_PATH_LITERAL("Move_To_Subdir"));
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Move_Test_File.txt"));
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the destination directory.
1072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_exists);
1073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_exists));
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(Move(dir_name_from, dir_name_to));
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been moved.
1078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(dir_name_from));
1079f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
1080f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryRecursivelyNew) {
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory.
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1088a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1089f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory.
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1095f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory.
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_from =
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_name_from);
1101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_name_from));
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the subdirectory.
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_from =
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name2_from));
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the directory recursively.
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_to =
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_to =
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(dir_name_to));
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, true));
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been copied.
1124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_from));
1125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_from));
1127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_from));
1128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
1130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_to));
1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_to));
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryRecursivelyExists) {
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory.
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory.
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_from =
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_name_from);
1151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_name_from));
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the subdirectory.
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_from =
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name2_from));
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the directory recursively.
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_exists =
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_exists.Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_to =
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_to =
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the destination directory.
1173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_exists);
1174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_exists));
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_exists, true));
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been copied.
1179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_from));
1180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_from));
1182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_from));
1183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
1185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_to));
1186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_to));
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryNew) {
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory.
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory.
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory.
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_from =
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_name_from);
1206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_name_from));
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the subdirectory.
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_from =
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name2_from));
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the directory not recursively.
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_to =
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(dir_name_to));
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been copied.
1227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_from));
1228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_from));
1230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_from));
1231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
1233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_name_to));
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryExists) {
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory.
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory.
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a subdirectory.
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_from =
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Subdir"));
1252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(subdir_name_from);
1253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(subdir_name_from));
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the subdirectory.
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name2_from =
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      subdir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name2_from, L"Gooooooooooooooooooooogle");
1259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name2_from));
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the directory not recursively.
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath subdir_name_to =
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Subdir"));
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the destination directory.
1270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_to);
1271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_to));
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(dir_name_from, dir_name_to, false));
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been copied.
1276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_from));
1277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(subdir_name_from));
1279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name2_from));
1280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
1282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(subdir_name_to));
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToNew) {
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination name
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to = temp_dir_.path().Append(
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
1295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(file_name_to));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the has been copied
1300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExisting) {
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination name
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to = temp_dir_.path().Append(
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE_PATH_LITERAL("Copy_Test_File_Destination.txt"));
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_to, L"Old file content");
1314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_to));
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(file_name_from, file_name_to, true));
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the has been copied
1319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(L"Gooooooooooooooooooooogle" == ReadTextFile(file_name_to));
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyFileWithCopyDirectoryRecursiveToExistingDirectory) {
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The destination
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to =
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Destination"));
1333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_to);
1334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_to));
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(file_name_from, dir_name_to, true));
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the has been copied
1341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryWithTrailingSeparators) {
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a directory.
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath dir_name_from =
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a file under the directory.
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath file_name_from =
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy the directory recursively.
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath dir_name_to =
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_To_Subdir"));
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath file_name_to =
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create from path with trailing separators.
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath from_path =
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir\\\\\\"));
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined (OS_POSIX)
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FilePath from_path =
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir///"));
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(CopyDirectory(from_path, dir_name_to, true));
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check everything has been copied.
1375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_from));
1376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Sets the source file to read-only.
13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SetReadOnly(const FilePath& path) {
13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // On Windows, it involves setting a bit.
13855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DWORD attrs = GetFileAttributes(path.value().c_str());
13865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(INVALID_FILE_ATTRIBUTES, attrs);
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(SetFileAttributes(
13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      path.value().c_str(), attrs | FILE_ATTRIBUTE_READONLY));
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  attrs = GetFileAttributes(path.value().c_str());
13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Files in the temporary directory should not be indexed ever. If this
13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // assumption change, fix this unit test accordingly.
13925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // FILE_ATTRIBUTE_NOT_CONTENT_INDEXED doesn't exist on XP.
13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DWORD expected = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY;
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (win::GetVersion() >= win::VERSION_VISTA)
13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expected |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
13965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(expected, attrs);
13975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // On all other platforms, it involves removing the write bit.
13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(SetPosixFilePermissions(path, S_IRUSR));
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsReadOnly(const FilePath& path) {
14045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
14055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DWORD attrs = GetFileAttributes(path.value().c_str());
14065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(INVALID_FILE_ATTRIBUTES, attrs);
14075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return attrs & FILE_ATTRIBUTE_READONLY;
14085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
14095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int mode = 0;
14105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(GetPosixFilePermissions(path, &mode));
14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !(mode & S_IWUSR);
14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
14135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FileUtilTest, CopyDirectoryACL) {
14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a directory.
14175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src"));
14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateDirectory(src);
14195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(PathExists(src));
14205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a file under the directory.
14225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath src_file = src.Append(FILE_PATH_LITERAL("src.txt"));
14235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateTextFile(src_file, L"Gooooooooooooooooooooogle");
14245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetReadOnly(src_file);
14255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(IsReadOnly(src_file));
14265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Copy the directory recursively.
14285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath dst = temp_dir_.path().Append(FILE_PATH_LITERAL("dst"));
14295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath dst_file = dst.Append(FILE_PATH_LITERAL("src.txt"));
14305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(CopyDirectory(src, dst, true));
14315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(IsReadOnly(dst_file));
14335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyFile) {
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("Copy_From_Subdir"));
1439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("Copy_Test_File.txt"));
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::wstring file_contents(L"Gooooooooooooooooooooogle");
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, file_contents);
1447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the file.
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dest_file = dir_name_from.Append(FILE_PATH_LITERAL("DestFile.txt"));
1451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CopyFile(file_name_from, dest_file));
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the file to another location using '..' in the path.
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dest_file2(dir_name_from);
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dest_file2 = dest_file2.AppendASCII("..");
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dest_file2 = dest_file2.AppendASCII("DestFile.txt");
1457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(CopyFile(file_name_from, dest_file2));
1458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(internal::CopyFileUnsafe(file_name_from, dest_file2));
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dest_file2_test(dir_name_from);
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dest_file2_test = dest_file2_test.DirName();
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dest_file2_test = dest_file2_test.AppendASCII("DestFile.txt");
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been copied.
1465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_from));
1466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dest_file));
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::wstring read_contents = ReadTextFile(dest_file);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_contents, read_contents);
1469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dest_file2_test));
1470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dest_file2));
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FileUtilTest, CopyFileACL) {
14745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // While FileUtilTest.CopyFile asserts the content is correctly copied over,
14755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this test case asserts the access control bits are meeting expectations in
14765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CopyFileUnsafe().
14775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath src = temp_dir_.path().Append(FILE_PATH_LITERAL("src.txt"));
14785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::wstring file_contents(L"Gooooooooooooooooooooogle");
14795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateTextFile(src, file_contents);
14805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set the source file to read-only.
14825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(IsReadOnly(src));
14835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetReadOnly(src);
14845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(IsReadOnly(src));
14855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Copy the file.
14875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath dst = temp_dir_.path().Append(FILE_PATH_LITERAL("dst.txt"));
14885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(CopyFile(src, dst));
14895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(file_contents, ReadTextFile(dst));
14905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(IsReadOnly(dst));
14925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file_util winds up using autoreleased objects on the Mac, so this needs
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be a PlatformTest.
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef PlatformTest ReadOnlyFileUtilTest;
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath data_dir;
1500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data_dir = data_dir.AppendASCII("file_util");
1502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(data_dir));
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath original_file =
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("original.txt"));
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath same_file =
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("same.txt"));
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath same_length_file =
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("same_length.txt"));
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_file =
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different.txt"));
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_first_file =
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_last_file =
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty1_file =
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty2_file =
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath shortened_file =
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath binary_file =
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("binary_file.bin"));
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath binary_file_same =
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("binary_file_same.bin"));
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath binary_file_diff =
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("binary_file_diff.bin"));
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(ContentsEqual(original_file, original_file));
15307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(ContentsEqual(original_file, same_file));
15317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(original_file, same_length_file));
15327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(original_file, different_file));
15337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(FilePath(FILE_PATH_LITERAL("bogusname")),
15347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             FilePath(FILE_PATH_LITERAL("bogusname"))));
15357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(original_file, different_first_file));
15367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(original_file, different_last_file));
15377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(ContentsEqual(empty1_file, empty2_file));
15387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(original_file, shortened_file));
15397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(shortened_file, original_file));
15407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(ContentsEqual(binary_file, binary_file_same));
15417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(ContentsEqual(binary_file, binary_file_diff));
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath data_dir;
1546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
1547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data_dir = data_dir.AppendASCII("file_util");
1548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(data_dir));
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath original_file =
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("original.txt"));
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath same_file =
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("same.txt"));
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath crlf_file =
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("crlf.txt"));
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath shortened_file =
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_file =
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different.txt"));
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_first_file =
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath different_last_file =
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath first1_file =
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("first1.txt"));
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath first2_file =
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("first2.txt"));
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty1_file =
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty2_file =
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath blank_line_file =
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("blank_line.txt"));
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath blank_line_crlf_file =
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(TextContentsEqual(original_file, same_file));
15787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(TextContentsEqual(original_file, crlf_file));
15797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(original_file, shortened_file));
15807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(original_file, different_file));
15817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(original_file, different_first_file));
15827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(original_file, different_last_file));
15837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(first1_file, first2_file));
15847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(TextContentsEqual(empty1_file, empty2_file));
15857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(TextContentsEqual(original_file, empty1_file));
15867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(TextContentsEqual(blank_line_file, blank_line_crlf_file));
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We don't need equivalent functionality outside of Windows.
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CopyAndDeleteDirectoryTest) {
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a directory
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_from =
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("CopyAndDelete_From_Subdir"));
1595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateDirectory(dir_name_from);
1596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(dir_name_from));
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file under the directory
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_from =
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_from.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(file_name_from, L"Gooooooooooooooooooooogle");
1602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_name_from));
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the directory by using CopyAndDeleteDirectory
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir_name_to = temp_dir_.path().Append(
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FILE_PATH_LITERAL("CopyAndDelete_To_Subdir"));
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_name_to =
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dir_name_to.Append(FILE_PATH_LITERAL("CopyAndDelete_Test_File.txt"));
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(dir_name_to));
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(internal::CopyAndDeleteDirectory(dir_name_from,
16137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                     dir_name_to));
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check everything has been moved.
1616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(dir_name_from));
1617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(file_name_from));
1618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(dir_name_to));
1619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(file_name_to));
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, GetTempDirTest) {
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const TCHAR* kTmpKey = _T("TMP");
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const TCHAR* kTmpValues[] = {
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _T(""), _T("C:"), _T("C:\\"), _T("C:\\tmp"), _T("C:\\tmp\\")
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Save the original $TMP.
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t original_tmp_size;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TCHAR* original_tmp;
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, ::_tdupenv_s(&original_tmp, &original_tmp_size, kTmpKey));
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // original_tmp may be NULL.
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned int i = 0; i < arraysize(kTmpValues); ++i) {
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FilePath path;
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::_tputenv_s(kTmpKey, kTmpValues[i]);
1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GetTempDir(&path);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(path.IsAbsolute()) << "$TMP=" << kTmpValues[i] <<
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        " result=" << path.value();
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restore the original $TMP.
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (original_tmp) {
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::_tputenv_s(kTmpKey, original_tmp);
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(original_tmp);
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::_tputenv_s(kTmpKey, _T(""));
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateTemporaryFileTest) {
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath temp_files[3];
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
1654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(CreateTemporaryFile(&(temp_files[i])));
1655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(PathExists(temp_files[i]));
16567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_FALSE(DirectoryExists(temp_files[i]));
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(temp_files[i] == temp_files[(i+1)%3]);
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++)
1661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(DeleteFile(temp_files[i], false));
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateAndOpenTemporaryFileTest) {
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath names[3];
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILE* fps[3];
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create; make sure they are open and exist.
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < 3; ++i) {
1671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fps[i] = CreateAndOpenTemporaryFile(&(names[i]));
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(fps[i]);
1673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(PathExists(names[i]));
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure all names are unique.
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < 3; ++i) {
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(names[i] == names[(i+1)%3]);
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close and delete.
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < 3; ++i) {
1683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(CloseFile(fps[i]));
1684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(DeleteFile(names[i], false));
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1688f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(FileUtilTest, FileToFILE) {
1689f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  File file;
1690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FILE* stream = FileToFILE(file.Pass(), "w");
1691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(stream);
1692f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1693f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FilePath file_name = temp_dir_.path().Append(FPL("The file.txt"));
1694f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  file = File(file_name, File::FLAG_CREATE | File::FLAG_WRITE);
1695f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(file.IsValid());
1696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  stream = FileToFILE(file.Pass(), "w");
1698f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(stream);
1699f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(file.IsValid());
1700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(CloseFile(stream));
1701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateNewTempDirectoryTest) {
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath temp_dir;
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateNewTempDirectory(FilePath::StringType(), &temp_dir));
1706f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(temp_dir));
1707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(temp_dir, false));
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath new_dir;
1712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateTemporaryDirInDir(
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  temp_dir_.path(),
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  FILE_PATH_LITERAL("CreateNewTemporaryDirInDirTest"),
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &new_dir));
1716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(new_dir));
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(temp_dir_.path().IsParent(new_dir));
1718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(new_dir, false));
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if defined(OS_POSIX)
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, GetShmemTempDirTest) {
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath dir;
1724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(GetShmemTempDir(false, &dir));
17257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(DirectoryExists(dir));
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
172723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(FileUtilTest, GetHomeDirTest) {
1730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_ANDROID)  // Not implemented on Android.
1731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We don't actually know what the home directory is supposed to be without
1732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // calling some OS functions which would just duplicate the implementation.
1733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // So here we just test that it returns something "reasonable".
1734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FilePath home = GetHomeDir();
1735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(home.empty());
1736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(home.IsAbsolute());
1737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
1738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, CreateDirectoryTest) {
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_root =
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test"));
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_path =
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_root.Append(FILE_PATH_LITERAL("dir\\tree\\likely\\doesnt\\exist\\"));
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_path =
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_root.Append(FILE_PATH_LITERAL("dir/tree/likely/doesnt/exist/"));
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_path));
1752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(test_path));
1753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(test_path));
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateDirectory returns true if the DirectoryExists returns true.
1755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(test_path));
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Doesn't work to create it on top of a non-dir
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_path = test_path.Append(FILE_PATH_LITERAL("foobar.txt"));
1759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_path));
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(test_path, L"test file");
1761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(test_path));
1762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(CreateDirectory(test_path));
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(test_root, true));
1765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_root));
1766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_path));
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify assumptions made by the Windows implementation:
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. The current directory always exists.
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. The root directory always exists.
17717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(DirectoryExists(FilePath(FilePath::kCurrentDirectory)));
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath top_level = test_root;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (top_level != top_level.DirName()) {
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    top_level = top_level.DirName();
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(DirectoryExists(top_level));
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given these assumptions hold, it should be safe to
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // test that "creating" these directories succeeds.
1780a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FilePath(FilePath::kCurrentDirectory)));
1782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(top_level));
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath invalid_drive(FILE_PATH_LITERAL("o:\\"));
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath invalid_path =
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      invalid_drive.Append(FILE_PATH_LITERAL("some\\inaccessible\\dir"));
1788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!PathExists(invalid_drive)) {
1789a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(CreateDirectory(invalid_path));
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, DetectDirectoryTest) {
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check a directory
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_root =
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("detect_directory_test"));
1798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_root));
1799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(test_root));
1800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(test_root));
18017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(DirectoryExists(test_root));
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check a file
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath test_path =
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_root.Append(FILE_PATH_LITERAL("foobar.txt"));
1805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(test_path));
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateTextFile(test_path, L"test file");
1807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(test_path));
18087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(DirectoryExists(test_path));
1809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(test_path, false));
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(DeleteFile(test_root, true));
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, FileEnumeratorTest) {
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an empty directory.
1816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
1817010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(FPL(""), f0.Next().value());
1818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(FPL(""), f0.Next().value());
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an empty directory, non-recursively, including "..".
1821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f0_dotdot(temp_dir_.path(), false,
1822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FILES_AND_DIRECTORIES | FileEnumerator::INCLUDE_DOT_DOT);
18233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(temp_dir_.path().Append(FPL("..")).value(),
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            f0_dotdot.Next().value());
18253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(FPL(""), f0_dotdot.Next().value());
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // create the directories
18283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath dir1 = temp_dir_.path().Append(FPL("dir1"));
1829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(dir1));
18303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath dir2 = temp_dir_.path().Append(FPL("dir2"));
1831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(dir2));
18323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath dir2inner = dir2.Append(FPL("inner"));
1833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(CreateDirectory(dir2inner));
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // create the files
18363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath dir2file = dir2.Append(FPL("dir2file.txt"));
1837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateTextFile(dir2file, std::wstring());
18383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath dir2innerfile = dir2inner.Append(FPL("innerfile.txt"));
1839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateTextFile(dir2innerfile, std::wstring());
18403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath file1 = temp_dir_.path().Append(FPL("file1.txt"));
1841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateTextFile(file1, std::wstring());
1842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FilePath file2_rel = dir2.Append(FilePath::kParentDirectory)
18433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .Append(FPL("file2.txt"));
1844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CreateTextFile(file2_rel, std::wstring());
18453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FilePath file2_abs = temp_dir_.path().Append(FPL("file2.txt"));
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only enumerate files.
1848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f1(temp_dir_.path(), true, FileEnumerator::FILES);
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c1(f1);
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c1.HasFile(file1));
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c1.HasFile(file2_abs));
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c1.HasFile(dir2file));
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c1.HasFile(dir2innerfile));
1854010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(4, c1.size());
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only enumerate directories.
1857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f2(temp_dir_.path(), true, FileEnumerator::DIRECTORIES);
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c2(f2);
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2.HasFile(dir1));
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2.HasFile(dir2));
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2.HasFile(dir2inner));
1862010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(3, c2.size());
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only enumerate directories non-recursively.
1865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f2_non_recursive(
1866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      temp_dir_.path(), false, FileEnumerator::DIRECTORIES);
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c2_non_recursive(f2_non_recursive);
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
1870010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(2, c2_non_recursive.size());
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only enumerate directories, non-recursively, including "..".
1873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f2_dotdot(temp_dir_.path(), false,
1874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           FileEnumerator::DIRECTORIES |
1875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           FileEnumerator::INCLUDE_DOT_DOT);
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c2_dotdot(f2_dotdot);
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2_dotdot.HasFile(dir1));
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c2_dotdot.HasFile(dir2));
18793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(c2_dotdot.HasFile(temp_dir_.path().Append(FPL(".."))));
1880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(3, c2_dotdot.size());
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerate files and directories.
1883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c3(f3);
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(dir1));
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(dir2));
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(file1));
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(file2_abs));
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(dir2file));
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(dir2inner));
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c3.HasFile(dir2innerfile));
1892010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(7, c3.size());
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-recursive operation.
1895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c4(f4);
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c4.HasFile(dir2));
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c4.HasFile(dir2));
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c4.HasFile(file1));
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c4.HasFile(file2_abs));
1901010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(4, c4.size());
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerate with a pattern.
19043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*"));
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindResultCollector c5(f5);
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c5.HasFile(dir1));
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c5.HasFile(dir2));
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c5.HasFile(dir2file));
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c5.HasFile(dir2inner));
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(c5.HasFile(dir2innerfile));
1911010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(5, c5.size());
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_WIN)
19143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
19153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Make dir1 point to dir2.
19163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ReparsePoint reparse_point(dir1, dir2);
19173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(reparse_point.IsValid());
19183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1919a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if ((win::GetVersion() >= win::VERSION_VISTA)) {
19203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // There can be a delay for the enumeration code to see the change on
19213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // the file system so skip this test for XP.
19223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // Enumerate the reparse point.
19233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      FileEnumerator f6(dir1, true, FILES_AND_DIRECTORIES);
19243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      FindResultCollector c6(f6);
19253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      FilePath inner2 = dir1.Append(FPL("inner"));
19263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      EXPECT_TRUE(c6.HasFile(inner2));
19273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt"))));
19283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt"))));
1929010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_EQ(3, c6.size());
19303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
19313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // No changes for non recursive operation.
19333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileEnumerator f7(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
19343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FindResultCollector c7(f7);
19353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c7.HasFile(dir2));
19363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c7.HasFile(dir2));
19373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c7.HasFile(file1));
19383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c7.HasFile(file2_abs));
1939010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(4, c7.size());
19403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Should not enumerate inside dir1 when using recursion.
19423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
19433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FindResultCollector c8(f8);
19443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(dir1));
19453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(dir2));
19463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(file1));
19473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(file2_abs));
19483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(dir2file));
19493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(dir2inner));
19503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_TRUE(c8.HasFile(dir2innerfile));
1951010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(7, c8.size());
19523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
19533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
19543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the destructor closes the find handle while in the middle of a
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // query to allow TearDown to delete the directory.
19573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FileEnumerator f9(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
19583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(f9.Next().value().empty());  // Should have found something
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            // (we don't care what).
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, AppendToFile) {
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath data_dir =
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a fresh, empty copy of this directory.
1967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (PathExists(data_dir)) {
1968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(DeleteFile(data_dir, true));
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1970a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(data_dir));
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a fresh, empty copy of this directory.
1973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (PathExists(data_dir)) {
1974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(DeleteFile(data_dir, true));
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(data_dir));
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data("hello");
1980a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(-1, AppendToFile(foobar, data.c_str(), data.length()));
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()),
1982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            WriteFile(foobar, data.c_str(), data.length()));
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(data.length()),
1984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            AppendToFile(foobar, data.c_str(), data.length()));
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::wstring read_content = ReadTextFile(foobar);
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(L"hellohello", read_content);
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19900529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(FileUtilTest, ReadFile) {
19910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Create a test file to be read.
19920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const std::string kTestData("The quick brown fox jumps over the lazy dog.");
19930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FilePath file_path =
19940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileTest"));
19950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(static_cast<int>(kTestData.size()),
19970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            WriteFile(file_path, kTestData.data(), kTestData.size()));
19980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make buffers with various size.
20000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<char> small_buffer(kTestData.size() / 2);
20010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<char> exact_buffer(kTestData.size());
20020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<char> large_buffer(kTestData.size() * 2);
20030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Read the file with smaller buffer.
20050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int bytes_read_small = ReadFile(
20060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      file_path, &small_buffer[0], static_cast<int>(small_buffer.size()));
2007010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(static_cast<int>(small_buffer.size()), bytes_read_small);
20080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(
2009010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string(kTestData.begin(), kTestData.begin() + small_buffer.size()),
2010010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string(small_buffer.begin(), small_buffer.end()));
20110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Read the file with buffer which have exactly same size.
20130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int bytes_read_exact = ReadFile(
20140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      file_path, &exact_buffer[0], static_cast<int>(exact_buffer.size()));
2015010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_exact);
2016010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(kTestData, std::string(exact_buffer.begin(), exact_buffer.end()));
20170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Read the file with larger buffer.
20190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int bytes_read_large = ReadFile(
20200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      file_path, &large_buffer[0], static_cast<int>(large_buffer.size()));
2021010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_large);
2022010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(kTestData, std::string(large_buffer.begin(),
2023010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   large_buffer.begin() + kTestData.size()));
20240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make sure the return value is -1 if the file doesn't exist.
20260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FilePath file_path_not_exist =
20270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileNotExistTest"));
20280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(-1,
20290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            ReadFile(file_path_not_exist,
20300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     &exact_buffer[0],
20310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     static_cast<int>(exact_buffer.size())));
20320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
20330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
20345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(FileUtilTest, ReadFileToString) {
20355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char kTestData[] = "0123";
20365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string data;
20375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FilePath file_path =
20395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
20405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FilePath file_path_dangerous =
20415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      temp_dir_.path().Append(FILE_PATH_LITERAL("..")).
20425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Append(temp_dir_.path().BaseName()).
20435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Append(FILE_PATH_LITERAL("ReadFileToStringTest"));
20445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Create test file.
2046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(4, WriteFile(file_path, kTestData, 4));
20475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ReadFileToString(file_path, &data));
20495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kTestData, data);
20505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data = "temp";
20525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ReadFileToString(file_path, &data, 0));
20535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0u, data.length());
20545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data = "temp";
20565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ReadFileToString(file_path, &data, 2));
20575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("01", data);
20585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.clear();
20605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ReadFileToString(file_path, &data, 3));
20615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("012", data);
20625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.clear();
20645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ReadFileToString(file_path, &data, 4));
20655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0123", data);
20665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.clear();
20685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ReadFileToString(file_path, &data, 6));
20695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0123", data);
20705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ReadFileToString(file_path, NULL, 6));
20725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(ReadFileToString(file_path, NULL));
20745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  data = "temp";
20765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(ReadFileToString(file_path_dangerous, &data));
20775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0u, data.length());
20785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
20795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Delete test file.
20805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(base::DeleteFile(file_path, false));
20815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2082a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data = "temp";
20835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ReadFileToString(file_path, &data));
20845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0u, data.length());
20855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data = "temp";
20875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(ReadFileToString(file_path, &data, 6));
20885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0u, data.length());
20895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
20905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, TouchFile) {
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath data_dir =
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest"));
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a fresh, empty copy of this directory.
2096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (PathExists(data_dir)) {
2097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(DeleteFile(data_dir, true));
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2099a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(data_dir));
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt")));
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data("hello");
2103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(WriteFile(foobar, data.c_str(), data.length()));
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Time access_time;
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This timestamp is divisible by one day (in local timezone),
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to make it work on FAT too.
2108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(Time::FromString("Wed, 16 Nov 1994, 00:00:00",
2109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               &access_time));
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Time modification_time;
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that this timestamp is divisible by two (seconds) - FAT stores
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // modification times with 2s resolution.
2114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT",
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &modification_time));
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(TouchFile(foobar, access_time, modification_time));
21185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  File::Info file_info;
2119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(GetFileInfo(foobar, &file_info));
2120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(access_time.ToInternalValue(),
2121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            file_info.last_accessed.ToInternalValue());
2122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(modification_time.ToInternalValue(),
2123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            file_info.last_modified.ToInternalValue());
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileUtilTest, IsDirectoryEmpty) {
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("EmptyDir"));
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(PathExists(empty_dir));
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(CreateDirectory(empty_dir));
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(IsDirectoryEmpty(empty_dir));
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt")));
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string bar("baz");
2137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(WriteFile(foo, bar.c_str(), bar.length()));
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(IsDirectoryEmpty(empty_dir));
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Testing VerifyPathControlledByAdmin() is hard, because there is no
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// way a test can make a file owned by root, or change file paths
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at the root of the file system.  VerifyPathControlledByAdmin()
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is implemented as a call to VerifyPathControlledByUser, which gives
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// us the ability to test with paths under the test's temp directory,
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using a user id we control.
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pull tests of VerifyPathControlledByUserTest() into a separate test class
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with a common SetUp() method.
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VerifyPathControlledByUserTest : public FileUtilTest {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileUtilTest::SetUp();
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a basic structure used by each test.
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // base_dir_
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //  |-> sub_dir_
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //       |-> text_file_
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base_dir_ = temp_dir_.path().AppendASCII("base_dir");
2163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(CreateDirectory(base_dir_));
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sub_dir_ = base_dir_.AppendASCII("sub_dir");
2166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(CreateDirectory(sub_dir_));
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text_file_ = sub_dir_.AppendASCII("file.txt");
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateTextFile(text_file_, L"This text file has some text in it.");
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get the user and group files are created with from |base_dir_|.
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct stat stat_buf;
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(0, stat(base_dir_.value().c_str(), &stat_buf));
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uid_ = stat_buf.st_uid;
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ok_gids_.insert(stat_buf.st_gid);
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bad_gids_.insert(stat_buf.st_gid + 1);
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(uid_, getuid());  // This process should be the owner.
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // To ensure that umask settings do not cause the initial state
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of permissions to be different from what we expect, explicitly
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // set permissions on the directories we create.
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make all files and directories non-world-writable.
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Users and group can read, write, traverse
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int enabled_permissions =
2187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FILE_PERMISSION_USER_MASK | FILE_PERMISSION_GROUP_MASK;
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Other users can't read, write, traverse
2189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int disabled_permissions = FILE_PERMISSION_OTHERS_MASK;
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ChangePosixFilePermissions(
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base_dir_, enabled_permissions, disabled_permissions));
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ChangePosixFilePermissions(
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sub_dir_, enabled_permissions, disabled_permissions));
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath base_dir_;
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath sub_dir_;
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath text_file_;
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uid_t uid_;
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<gid_t> ok_gids_;
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<gid_t> bad_gids_;
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VerifyPathControlledByUserTest, BadPaths) {
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // File does not exist.
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath does_not_exist = base_dir_.AppendASCII("does")
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     .AppendASCII("not")
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     .AppendASCII("exist");
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, does_not_exist, uid_, ok_gids_));
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |base| not a subpath of |path|.
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, base_dir_, uid_, ok_gids_));
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An empty base path will fail to be a prefix for any path.
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath empty;
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          empty, base_dir_, uid_, ok_gids_));
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finding that a bad call fails proves nothing unless a good call succeeds.
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VerifyPathControlledByUserTest, Symlinks) {
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Symlinks in the path should cause failure.
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Symlink to the file at the end of the path.
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_link =  base_dir_.AppendASCII("file_link");
2239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(text_file_, file_link))
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Failed to create symlink.";
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, file_link, uid_, ok_gids_));
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          file_link, file_link, uid_, ok_gids_));
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Symlink from one directory to another within the path.
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath link_to_sub_dir =  base_dir_.AppendASCII("link_to_sub_dir");
2251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(CreateSymbolicLink(sub_dir_, link_to_sub_dir))
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    << "Failed to create symlink.";
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt");
2255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(file_path_with_link));
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, file_path_with_link, uid_, ok_gids_));
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          link_to_sub_dir, file_path_with_link, uid_, ok_gids_));
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Symlinks in parents of base path are allowed.
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          file_path_with_link, file_path_with_link, uid_, ok_gids_));
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) {
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get a uid that is not the uid of files we create.
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uid_t bad_uid = uid_ + 1;
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all files and directories non-world-writable.
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We control these paths.
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Another user does not control these paths.
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, bad_uid, ok_gids_));
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, bad_uid, ok_gids_));
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, bad_uid, ok_gids_));
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Another group does not control the paths.
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, bad_gids_));
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, bad_gids_));
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, bad_gids_));
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) {
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all files and directories writable only by their owner.
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP));
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP));
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP));
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Any group is okay because the path is not group-writable.
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, bad_gids_));
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, bad_gids_));
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, bad_gids_));
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No group is okay, because we don't check the group
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if no group can write.
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<gid_t> no_gids;  // Empty set of gids.
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, no_gids));
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, no_gids));
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, no_gids));
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all files and directories writable by their group.
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u));
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u));
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, S_IWGRP, 0u));
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now |ok_gids_| works, but |bad_gids_| fails.
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, bad_gids_));
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, bad_gids_));
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, bad_gids_));
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because any group in the group set is allowed,
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the union of good and bad gids passes.
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<gid_t> multiple_gids;
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set_union(
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ok_gids_.begin(), ok_gids_.end(),
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_gids_.begin(), bad_gids_.end(),
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::inserter(multiple_gids, multiple_gids.begin()));
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, multiple_gids));
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, multiple_gids));
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, multiple_gids));
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) {
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all files and directories non-world-writable.
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialy, we control all parts of the path.
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make base_dir_ world-writable.
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u));
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sub_dir_ world writable.
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u));
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make text_file_ world writable.
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, S_IWOTH, 0u));
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sub_dir_ non-world writable.
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH));
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make base_dir_ non-world-writable.
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH));
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
2492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Back to the initial state: Nothing is writable, so every path
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should pass.
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangePosixFilePermissions(text_file_, 0u, S_IWOTH));
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, sub_dir_, uid_, ok_gids_));
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base_dir_, text_file_, uid_, ok_gids_));
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
2506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::VerifyPathControlledByUser(
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sub_dir_, text_file_, uid_, ok_gids_));
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
2511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FileUtilTest, ValidContentUriTest) {
2512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Get the test image path.
2513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FilePath data_dir;
2514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &data_dir));
2515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  data_dir = data_dir.AppendASCII("file_util");
2516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(PathExists(data_dir));
2517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FilePath image_file = data_dir.Append(FILE_PATH_LITERAL("red.png"));
2518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 image_size;
2519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetFileSize(image_file, &image_size);
2520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_LT(0, image_size);
2521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Insert the image into MediaStore. MediaStore will do some conversions, and
2523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // return the content URI.
25246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FilePath path = base::InsertImageIntoMediaStore(image_file);
2525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(path.IsContentUri());
2526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(PathExists(path));
2527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The file size may not equal to the input image as MediaStore may convert
2528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the image.
2529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 content_uri_size;
2530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetFileSize(path, &content_uri_size);
2531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(image_size, content_uri_size);
2532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We should be able to read the file.
2534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  char* buffer = new char[image_size];
253523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  File file = OpenContentUriForRead(path);
253623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(file.IsValid());
253723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(file.ReadAtCurrentPos(buffer, image_size));
2538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete[] buffer;
2539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(FileUtilTest, NonExistentContentUriTest) {
2542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FilePath path("content://foo.bar");
2543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(path.IsContentUri());
2544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(PathExists(path));
2545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Size should be smaller than 0.
2546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 size;
2547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetFileSize(path, &size));
2548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We should not be able to read the file.
255023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  File file = OpenContentUriForRead(path);
255123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(file.IsValid());
2552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
2554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(ScopedFD, ScopedFDDoesClose) {
2556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int fds[2];
2557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  char c = 0;
2558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, pipe(fds));
2559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int write_end = fds[1];
2560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ScopedFD read_end_closer(fds[0]);
2561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  {
2562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::ScopedFD write_end_closer(fds[1]);
2563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This is the only thread. This file descriptor should no longer be valid.
2565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int ret = close(write_end);
2566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(-1, ret);
2567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(EBADF, errno);
2568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure read(2) won't block.
2569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, fcntl(fds[0], F_SETFL, O_NONBLOCK));
2570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reading the pipe should EOF.
2571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, read(fds[0], &c, 1));
2572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(GTEST_HAS_DEATH_TEST)
2575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CloseWithScopedFD(int fd) {
2576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ScopedFD fd_closer(fd);
2577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
2579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(ScopedFD, ScopedFDCrashesOnCloseFailure) {
2581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int fds[2];
2582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, pipe(fds));
2583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ScopedFD read_end_closer(fds[0]);
2584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, IGNORE_EINTR(close(fds[1])));
2585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(GTEST_HAS_DEATH_TEST)
2586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This is the only thread. This file descriptor should no longer be valid.
2587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Trying to close it should crash. This is important for security.
2588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_DEATH(CloseWithScopedFD(fds[1]), "");
2589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
2590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace base
2597