Flutter Engine
file_unittest.cc File Reference
#include <cstring>
#include <memory>
#include <vector>
#include "flutter/fml/build_config.h"
#include "flutter/fml/file.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/unique_fd.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Macros

#define AtomicWriteTest   AtomicWriteTest
 

Functions

static bool WriteStringToFile (const fml::UniqueFD &fd, const std::string &contents)
 
static std::string ReadStringFromFile (const fml::UniqueFD &fd)
 
 TEST (FileTest, CreateTemporaryAndUnlink)
 
 TEST (FileTest, ScopedTempDirIsValid)
 
 TEST (FileTest, CanOpenFileForWriting)
 
 TEST (FileTest, CanTruncateAndWrite)
 
 TEST (FileTest, CreateDirectoryStructure)
 
 TEST (FileTest, VisitFilesCanBeCalledTwice)
 
 TEST (FileTest, CanListFilesRecursively)
 
 TEST (FileTest, CanStopVisitEarly)
 
 TEST (FileTest, AtomicWriteTest)
 
 TEST (FileTest, EmptyMappingTest)
 
 TEST (FileTest, FileTestsWork)
 
 TEST (FileTest, FileTestsSupportsUnicode)
 

Macro Definition Documentation

◆ AtomicWriteTest

#define AtomicWriteTest   AtomicWriteTest

Definition at line 234 of file file_unittest.cc.

Function Documentation

◆ ReadStringFromFile()

static std::string ReadStringFromFile ( const fml::UniqueFD fd)
static

Definition at line 35 of file file_unittest.cc.

References fml::FileMapping::GetMapping(), and fml::FileMapping::GetSize().

Referenced by TEST().

35  {
36  fml::FileMapping mapping(fd);
37 
38  if (mapping.GetMapping() == nullptr) {
39  return nullptr;
40  }
41 
42  return {reinterpret_cast<const char*>(mapping.GetMapping()),
43  mapping.GetSize()};
44 }

◆ TEST() [1/12]

TEST ( FileTest  ,
CreateTemporaryAndUnlink   
)

Definition at line 46 of file file_unittest.cc.

References fml::CreateTemporaryDirectory(), fml::kRead, fml::OpenDirectory(), fml::UniqueObject< T, Traits >::reset(), and fml::UnlinkDirectory().

46  {
47  auto dir_name = fml::CreateTemporaryDirectory();
48  ASSERT_NE(dir_name, "");
49  auto dir =
50  fml::OpenDirectory(dir_name.c_str(), false, fml::FilePermission::kRead);
51  ASSERT_TRUE(dir.is_valid());
52  dir.reset();
53  ASSERT_TRUE(fml::UnlinkDirectory(dir_name.c_str()));
54 }
std::string CreateTemporaryDirectory()
Definition: file_posix.cc:23
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition: file_posix.cc:94
bool UnlinkDirectory(const char *path)
Definition: file_posix.cc:160

◆ TEST() [2/12]

TEST ( FileTest  ,
ScopedTempDirIsValid   
)

Definition at line 56 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), and fml::UniqueObject< T, Traits >::is_valid().

56  {
58  ASSERT_TRUE(dir.fd().is_valid());
59 }
bool is_valid() const
Definition: unique_object.h:89
const UniqueFD & fd()
Definition: file.h:147

◆ TEST() [3/12]

TEST ( FileTest  ,
CanOpenFileForWriting   
)

Definition at line 61 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::UniqueObject< T, Traits >::is_valid(), fml::kWrite, fml::OpenFile(), fml::UniqueObject< T, Traits >::reset(), and fml::UnlinkFile().

61  {
63  ASSERT_TRUE(dir.fd().is_valid());
64 
65  auto fd =
66  fml::OpenFile(dir.fd(), "some.txt", true, fml::FilePermission::kWrite);
67  ASSERT_TRUE(fd.is_valid());
68  fd.reset();
69  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "some.txt"));
70 }
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
bool is_valid() const
Definition: unique_object.h:89
const UniqueFD & fd()
Definition: file.h:147
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64

◆ TEST() [4/12]

TEST ( FileTest  ,
CanTruncateAndWrite   
)

Definition at line 72 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::UniqueObject< T, Traits >::is_valid(), fml::kRead, fml::kReadWrite, fml::FileMapping::kWrite, fml::OpenFile(), fml::TruncateFile(), and fml::UnlinkFile().

72  {
74  ASSERT_TRUE(dir.fd().is_valid());
75 
76  std::string contents = "some contents here";
77 
78  {
79  auto fd = fml::OpenFile(dir.fd(), "some.txt", true,
81  ASSERT_TRUE(fd.is_valid());
82 
83  ASSERT_TRUE(fml::TruncateFile(fd, contents.size()));
84 
86  ASSERT_EQ(mapping.GetSize(), contents.size());
87  ASSERT_NE(mapping.GetMutableMapping(), nullptr);
88 
89  ::memcpy(mapping.GetMutableMapping(), contents.data(), contents.size());
90  }
91 
92  {
93  auto fd =
94  fml::OpenFile(dir.fd(), "some.txt", false, fml::FilePermission::kRead);
95  ASSERT_TRUE(fd.is_valid());
96 
97  fml::FileMapping mapping(fd);
98  ASSERT_EQ(mapping.GetSize(), contents.size());
99 
100  ASSERT_EQ(0,
101  ::memcmp(mapping.GetMapping(), contents.data(), contents.size()));
102  }
103 
104  fml::UnlinkFile(dir.fd(), "some.txt");
105 }
bool is_valid() const
Definition: unique_object.h:89
const UniqueFD & fd()
Definition: file.h:147
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64
bool TruncateFile(const fml::UniqueFD &file, size_t size)
Definition: file_posix.cc:152

◆ TEST() [5/12]

TEST ( FileTest  ,
CreateDirectoryStructure   
)

Definition at line 107 of file file_unittest.cc.

References fml::CreateDirectory(), fml::ScopedTemporaryDirectory::fd(), fml::kRead, fml::kReadWrite, fml::OpenFile(), ReadStringFromFile(), fml::UnlinkDirectory(), fml::UnlinkFile(), and WriteStringToFile().

107  {
109 
110  std::string contents = "These are my contents";
111  {
112  auto sub = fml::CreateDirectory(dir.fd(), {"a", "b", "c"},
114  ASSERT_TRUE(sub.is_valid());
115  auto file = fml::OpenFile(sub, "my_contents", true,
117  ASSERT_TRUE(file.is_valid());
118  ASSERT_TRUE(WriteStringToFile(file, contents));
119  }
120 
121  const char* file_path = "a/b/c/my_contents";
122 
123  {
124  auto contents_file =
125  fml::OpenFile(dir.fd(), file_path, false, fml::FilePermission::kRead);
126  ASSERT_EQ(ReadStringFromFile(contents_file), contents);
127  }
128 
129  // Cleanup.
130  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), file_path));
131  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
132  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
133  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
134 }
static std::string ReadStringFromFile(const fml::UniqueFD &fd)
const UniqueFD & fd()
Definition: file.h:147
static fml::UniqueFD CreateDirectory(const fml::UniqueFD &base_directory, const std::vector< std::string > &components, FilePermission permission, size_t index)
Definition: file.cc:12
static bool WriteStringToFile(const fml::UniqueFD &fd, const std::string &contents)
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64
bool UnlinkDirectory(const char *path)
Definition: file_posix.cc:160

◆ TEST() [6/12]

TEST ( FileTest  ,
VisitFilesCanBeCalledTwice   
)

Definition at line 136 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::kReadWrite, fml::OpenFile(), fml::UnlinkFile(), and fml::VisitFiles().

136  {
138 
139  {
140  auto file = fml::OpenFile(dir.fd(), "my_contents", true,
142  ASSERT_TRUE(file.is_valid());
143  }
144 
145  int count;
146  fml::FileVisitor count_visitor = [&count](const fml::UniqueFD& directory,
147  const std::string& filename) {
148  count += 1;
149  return true;
150  };
151  count = 0;
152  fml::VisitFiles(dir.fd(), count_visitor);
153  ASSERT_EQ(count, 1);
154 
155  // Without `rewinddir` in `VisitFiles`, the following check would fail.
156  count = 0;
157  fml::VisitFiles(dir.fd(), count_visitor);
158  ASSERT_EQ(count, 1);
159 
160  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
161 }
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98
bool VisitFiles(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file_posix.cc:233
const UniqueFD & fd()
Definition: file.h:147
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64

◆ TEST() [7/12]

TEST ( FileTest  ,
CanListFilesRecursively   
)

Definition at line 163 of file file_unittest.cc.

References fml::CreateDirectory(), fml::ScopedTemporaryDirectory::fd(), fml::kReadWrite, fml::OpenFile(), fml::UnlinkDirectory(), fml::UnlinkFile(), and fml::VisitFilesRecursively().

163  {
165 
166  {
167  auto c = fml::CreateDirectory(dir.fd(), {"a", "b", "c"},
169  ASSERT_TRUE(c.is_valid());
170  auto file1 =
172  auto file2 =
175  ASSERT_TRUE(d.is_valid());
176  auto file3 =
178  ASSERT_TRUE(file1.is_valid());
179  ASSERT_TRUE(file2.is_valid());
180  ASSERT_TRUE(file3.is_valid());
181  }
182 
183  std::set<std::string> names;
184  fml::FileVisitor visitor = [&names](const fml::UniqueFD& directory,
185  const std::string& filename) {
186  names.insert(filename);
187  return true;
188  };
189 
190  fml::VisitFilesRecursively(dir.fd(), visitor);
191  ASSERT_EQ(names, std::set<std::string>(
192  {"a", "b", "c", "d", "file1", "file2", "file3"}));
193 
194  // Cleanup.
195  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/d/file3"));
196  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/file1"));
197  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/file2"));
198  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c/d"));
199  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
200  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
201  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
202 }
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98
const UniqueFD & fd()
Definition: file.h:147
static fml::UniqueFD CreateDirectory(const fml::UniqueFD &base_directory, const std::vector< std::string > &components, FilePermission permission, size_t index)
Definition: file.cc:12
bool VisitFilesRecursively(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file.cc:71
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64
bool UnlinkDirectory(const char *path)
Definition: file_posix.cc:160

◆ TEST() [8/12]

TEST ( FileTest  ,
CanStopVisitEarly   
)

Definition at line 204 of file file_unittest.cc.

References fml::CreateDirectory(), fml::ScopedTemporaryDirectory::fd(), fml::kReadWrite, fml::UnlinkDirectory(), and fml::VisitFilesRecursively().

204  {
206 
207  {
208  auto d = fml::CreateDirectory(dir.fd(), {"a", "b", "c", "d"},
210  ASSERT_TRUE(d.is_valid());
211  }
212 
213  std::set<std::string> names;
214  fml::FileVisitor visitor = [&names](const fml::UniqueFD& directory,
215  const std::string& filename) {
216  names.insert(filename);
217  return filename == "c" ? false : true; // stop if c is found
218  };
219 
220  // Check the d is not visited as we stop at c.
221  ASSERT_FALSE(fml::VisitFilesRecursively(dir.fd(), visitor));
222  ASSERT_EQ(names, std::set<std::string>({"a", "b", "c"}));
223 
224  // Cleanup.
225  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c/d"));
226  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
227  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
228  ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
229 }
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition: file.h:98
const UniqueFD & fd()
Definition: file.h:147
static fml::UniqueFD CreateDirectory(const fml::UniqueFD &base_directory, const std::vector< std::string > &components, FilePermission permission, size_t index)
Definition: file.cc:12
bool VisitFilesRecursively(const fml::UniqueFD &directory, const FileVisitor &visitor)
Definition: file.cc:71
bool UnlinkDirectory(const char *path)
Definition: file_posix.cc:160

◆ TEST() [9/12]

TEST ( FileTest  ,
AtomicWriteTest   
)

Definition at line 236 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::kRead, fml::OpenFile(), ReadStringFromFile(), fml::UnlinkFile(), and fml::WriteAtomically().

236  {
238 
239  const std::string contents = "These are my contents.";
240 
241  auto data = std::make_unique<fml::DataMapping>(
242  std::vector<uint8_t>{contents.begin(), contents.end()});
243 
244  // Write.
245  ASSERT_TRUE(fml::WriteAtomically(dir.fd(), "precious_data", *data));
246 
247  // Read and verify.
248  ASSERT_EQ(contents,
249  ReadStringFromFile(fml::OpenFile(dir.fd(), "precious_data", false,
251 
252  // Cleanup.
253  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "precious_data"));
254 }
static std::string ReadStringFromFile(const fml::UniqueFD &fd)
const UniqueFD & fd()
Definition: file.h:147
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
Definition: file_posix.cc:188

◆ TEST() [10/12]

TEST ( FileTest  ,
EmptyMappingTest   
)

Definition at line 256 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::kReadWrite, fml::OpenFile(), and fml::UnlinkFile().

256  {
258 
259  {
260  auto file = fml::OpenFile(dir.fd(), "my_contents", true,
262 
263  fml::FileMapping mapping(file);
264  ASSERT_TRUE(mapping.IsValid());
265  ASSERT_EQ(mapping.GetSize(), 0ul);
266  ASSERT_EQ(mapping.GetMapping(), nullptr);
267  }
268 
269  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
270 }
const UniqueFD & fd()
Definition: file.h:147
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64

◆ TEST() [11/12]

TEST ( FileTest  ,
FileTestsWork   
)

Definition at line 272 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::FileExists(), fml::UniqueObject< T, Traits >::is_valid(), fml::IsFile(), fml::paths::JoinPaths(), fml::kWrite, fml::OpenFile(), fml::ScopedTemporaryDirectory::path(), fml::UniqueObject< T, Traits >::reset(), and fml::UnlinkFile().

272  {
274  ASSERT_TRUE(dir.fd().is_valid());
275  const char* filename = "some.txt";
276  auto fd =
277  fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
278  ASSERT_TRUE(fd.is_valid());
279  fd.reset();
280  ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
281  ASSERT_TRUE(
282  fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
283  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
284 }
const std::string & path() const
Definition: file.h:146
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
bool is_valid() const
Definition: unique_object.h:89
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
const UniqueFD & fd()
Definition: file.h:147
bool FileExists(const fml::UniqueFD &base_directory, const char *path)
Definition: file_posix.cc:180
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
bool IsFile(const std::string &path)
Definition: file_posix.cc:143
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64

◆ TEST() [12/12]

TEST ( FileTest  ,
FileTestsSupportsUnicode   
)

Definition at line 286 of file file_unittest.cc.

References fml::ScopedTemporaryDirectory::fd(), fml::FileExists(), fml::UniqueObject< T, Traits >::is_valid(), fml::IsFile(), fml::paths::JoinPaths(), fml::kWrite, fml::OpenFile(), fml::ScopedTemporaryDirectory::path(), fml::UniqueObject< T, Traits >::reset(), and fml::UnlinkFile().

286  {
288  ASSERT_TRUE(dir.fd().is_valid());
289  const char* filename = u8"äëïöüテスト☃";
290  auto fd =
291  fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
292  ASSERT_TRUE(fd.is_valid());
293  fd.reset();
294  ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
295  ASSERT_TRUE(
296  fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
297  ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
298 }
const std::string & path() const
Definition: file.h:146
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
bool is_valid() const
Definition: unique_object.h:89
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
const UniqueFD & fd()
Definition: file.h:147
bool FileExists(const fml::UniqueFD &base_directory, const char *path)
Definition: file_posix.cc:180
bool UnlinkFile(const char *path)
Definition: file_posix.cc:168
bool IsFile(const std::string &path)
Definition: file_posix.cc:143
fml::UniqueFD OpenFile(const char *path, bool create_if_necessary, FilePermission permission)
This can open a directory on POSIX, but not on Windows.
Definition: file_posix.cc:64

◆ WriteStringToFile()

static bool WriteStringToFile ( const fml::UniqueFD fd,
const std::string &  contents 
)
static

Definition at line 16 of file file_unittest.cc.

References fml::FileMapping::kWrite, and fml::TruncateFile().

Referenced by TEST().

17  {
18  if (!fml::TruncateFile(fd, contents.size())) {
19  return false;
20  }
21 
23  if (mapping.GetSize() != contents.size()) {
24  return false;
25  }
26 
27  if (mapping.GetMutableMapping() == nullptr) {
28  return false;
29  }
30 
31  ::memmove(mapping.GetMutableMapping(), contents.data(), contents.size());
32  return true;
33 }
bool TruncateFile(const fml::UniqueFD &file, size_t size)
Definition: file_posix.cc:152