Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
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.

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, IgnoreBaseDirWhenPathIsAbsolute)
 
 TEST (FileTest, EmptyMappingTest)
 
 TEST (FileTest, MappingDontNeedSafeTest)
 
 TEST (FileTest, FileTestsWork)
 
 TEST (FileTest, FileTestsSupportsUnicode)
 

Function Documentation

◆ ReadStringFromFile()

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

Definition at line 35 of file file_unittest.cc.

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/14]

TEST ( FileTest  ,
AtomicWriteTest   
)

Definition at line 236 of file file_unittest.cc.

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)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition switches.h:145
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
bool UnlinkFile(const char *path)
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:66

◆ TEST() [2/14]

TEST ( FileTest  ,
CanListFilesRecursively   
)

Definition at line 168 of file file_unittest.cc.

168 {
170
171 {
172 auto c = fml::CreateDirectory(dir.fd(), {"a", "b", "c"},
174 ASSERT_TRUE(c.is_valid());
175 auto file1 =
177 auto file2 =
180 ASSERT_TRUE(d.is_valid());
181 auto file3 =
183 ASSERT_TRUE(file1.is_valid());
184 ASSERT_TRUE(file2.is_valid());
185 ASSERT_TRUE(file3.is_valid());
186 }
187
188 std::set<std::string> names;
189 fml::FileVisitor visitor = [&names](const fml::UniqueFD& directory,
190 const std::string& filename) {
191 names.insert(filename);
192 return true;
193 };
194
195 fml::VisitFilesRecursively(dir.fd(), visitor);
196 ASSERT_EQ(names, std::set<std::string>(
197 {"a", "b", "c", "d", "file1", "file2", "file3"}));
198
199 // Cleanup.
200 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/d/file3"));
201 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/file1"));
202 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "a/b/c/file2"));
203 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c/d"));
204 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
205 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
206 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
207}
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
bool UnlinkDirectory(const char *path)
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
std::function< bool(const fml::UniqueFD &directory, const std::string &filename)> FileVisitor
Definition file.h:98

◆ TEST() [3/14]

TEST ( FileTest  ,
CanOpenFileForWriting   
)

Definition at line 61 of file file_unittest.cc.

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}

◆ TEST() [4/14]

TEST ( FileTest  ,
CanStopVisitEarly   
)

Definition at line 209 of file file_unittest.cc.

209 {
211
212 {
213 auto d = fml::CreateDirectory(dir.fd(), {"a", "b", "c", "d"},
215 ASSERT_TRUE(d.is_valid());
216 }
217
218 std::set<std::string> names;
219 fml::FileVisitor visitor = [&names](const fml::UniqueFD& directory,
220 const std::string& filename) {
221 names.insert(filename);
222 return filename == "c" ? false : true; // stop if c is found
223 };
224
225 // Check the d is not visited as we stop at c.
226 ASSERT_FALSE(fml::VisitFilesRecursively(dir.fd(), visitor));
227 ASSERT_EQ(names, std::set<std::string>({"a", "b", "c"}));
228
229 // Cleanup.
230 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c/d"));
231 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
232 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
233 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
234}

◆ TEST() [5/14]

TEST ( FileTest  ,
CanTruncateAndWrite   
)

Definition at line 72 of file file_unittest.cc.

72 {
74 ASSERT_TRUE(dir.fd().is_valid());
75
76 std::string contents = "some contents here";
77
78 // On the first iteration, this tests writing and then reading a file that
79 // didn't exist yet. On the second iteration it tests truncating, writing,
80 // and reading a file that already existed.
81 for (int i = 0; i < 2; i++) {
82 {
83 auto fd = fml::OpenFile(dir.fd(), "some.txt", true,
85 ASSERT_TRUE(fd.is_valid());
86
87 ASSERT_TRUE(fml::TruncateFile(fd, contents.size()));
88
90 ASSERT_EQ(mapping.GetSize(), contents.size());
91 ASSERT_NE(mapping.GetMutableMapping(), nullptr);
92
93 ::memcpy(mapping.GetMutableMapping(), contents.data(), contents.size());
94 }
95
96 {
97 auto fd = fml::OpenFile(dir.fd(), "some.txt", false,
99 ASSERT_TRUE(fd.is_valid());
100
101 fml::FileMapping mapping(fd);
102 ASSERT_EQ(mapping.GetSize(), contents.size());
103
104 ASSERT_EQ(
105 0, ::memcmp(mapping.GetMapping(), contents.data(), contents.size()));
106 }
107 }
108
109 fml::UnlinkFile(dir.fd(), "some.txt");
110}
bool TruncateFile(const fml::UniqueFD &file, size_t size)

◆ TEST() [6/14]

TEST ( FileTest  ,
CreateDirectoryStructure   
)

Definition at line 112 of file file_unittest.cc.

112 {
114
115 std::string contents = "These are my contents";
116 {
117 auto sub = fml::CreateDirectory(dir.fd(), {"a", "b", "c"},
119 ASSERT_TRUE(sub.is_valid());
120 auto file = fml::OpenFile(sub, "my_contents", true,
122 ASSERT_TRUE(file.is_valid());
123 ASSERT_TRUE(WriteStringToFile(file, contents));
124 }
125
126 const char* file_path = "a/b/c/my_contents";
127
128 {
129 auto contents_file =
130 fml::OpenFile(dir.fd(), file_path, false, fml::FilePermission::kRead);
131 ASSERT_EQ(ReadStringFromFile(contents_file), contents);
132 }
133
134 // Cleanup.
135 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), file_path));
136 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b/c"));
137 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a/b"));
138 ASSERT_TRUE(fml::UnlinkDirectory(dir.fd(), "a"));
139}
static bool WriteStringToFile(const fml::UniqueFD &fd, const std::string &contents)

◆ TEST() [7/14]

TEST ( FileTest  ,
CreateTemporaryAndUnlink   
)

Definition at line 46 of file file_unittest.cc.

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}
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition file_posix.cc:97
std::string CreateTemporaryDirectory()
Definition file_posix.cc:25

◆ TEST() [8/14]

TEST ( FileTest  ,
EmptyMappingTest   
)

Definition at line 283 of file file_unittest.cc.

283 {
285
286 {
287 auto file = fml::OpenFile(dir.fd(), "my_contents", true,
289
290 fml::FileMapping mapping(file);
291 ASSERT_TRUE(mapping.IsValid());
292 ASSERT_EQ(mapping.GetSize(), 0ul);
293 ASSERT_EQ(mapping.GetMapping(), nullptr);
294 }
295
296 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
297}

◆ TEST() [9/14]

TEST ( FileTest  ,
FileTestsSupportsUnicode   
)

Definition at line 343 of file file_unittest.cc.

343 {
345 ASSERT_TRUE(dir.fd().is_valid());
346 const char* filename = u8"äëïöüテスト☃";
347 auto fd =
348 fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
349 ASSERT_TRUE(fd.is_valid());
350 fd.reset();
351 ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
352 ASSERT_TRUE(
353 fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
354 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
355}
const SkPath & path() const
Definition path.h:117
std::string JoinPaths(std::initializer_list< std::string > components)
Definition paths.cc:14
bool IsFile(const std::string &path)
bool FileExists(const fml::UniqueFD &base_directory, const char *path)

◆ TEST() [10/14]

TEST ( FileTest  ,
FileTestsWork   
)

Definition at line 329 of file file_unittest.cc.

329 {
331 ASSERT_TRUE(dir.fd().is_valid());
332 const char* filename = "some.txt";
333 auto fd =
334 fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
335 ASSERT_TRUE(fd.is_valid());
336 fd.reset();
337 ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
338 ASSERT_TRUE(
339 fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
340 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
341}

◆ TEST() [11/14]

TEST ( FileTest  ,
IgnoreBaseDirWhenPathIsAbsolute   
)

Definition at line 256 of file file_unittest.cc.

256 {
258
259 // Make an absolute path.
260 std::string filename = "filename.txt";
261 std::string full_path =
263
264 const std::string contents = "These are my contents.";
265 auto data = std::make_unique<fml::DataMapping>(
266 std::vector<uint8_t>{contents.begin(), contents.end()});
267
268 // Write.
269 ASSERT_TRUE(fml::WriteAtomically(dir.fd(), full_path.c_str(), *data));
270
271 // Test existence.
272 ASSERT_TRUE(fml::FileExists(dir.fd(), full_path.c_str()));
273
274 // Read and verify.
275 ASSERT_EQ(contents,
276 ReadStringFromFile(fml::OpenFile(dir.fd(), full_path.c_str(), false,
278
279 // Cleanup.
280 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), full_path.c_str()));
281}
std::string AbsolutePath(const std::string &path)

◆ TEST() [12/14]

TEST ( FileTest  ,
MappingDontNeedSafeTest   
)

Definition at line 299 of file file_unittest.cc.

299 {
301
302 {
303 auto file = fml::OpenFile(dir.fd(), "my_contents", true,
305 WriteStringToFile(file, "some content");
306 }
307
308 {
309 auto file = fml::OpenFile(dir.fd(), "my_contents", false,
311 fml::FileMapping mapping(file);
312 ASSERT_TRUE(mapping.IsValid());
313 ASSERT_EQ(mapping.GetMutableMapping(), nullptr);
314 ASSERT_TRUE(mapping.IsDontNeedSafe());
315 }
316
317 {
318 auto file = fml::OpenFile(dir.fd(), "my_contents", false,
322 ASSERT_TRUE(mapping.IsValid());
323 ASSERT_NE(mapping.GetMutableMapping(), nullptr);
324 ASSERT_FALSE(mapping.IsDontNeedSafe());
325 }
326 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
327}

◆ TEST() [13/14]

TEST ( FileTest  ,
ScopedTempDirIsValid   
)

Definition at line 56 of file file_unittest.cc.

56 {
58 ASSERT_TRUE(dir.fd().is_valid());
59}

◆ TEST() [14/14]

TEST ( FileTest  ,
VisitFilesCanBeCalledTwice   
)

Definition at line 141 of file file_unittest.cc.

141 {
143
144 {
145 auto file = fml::OpenFile(dir.fd(), "my_contents", true,
147 ASSERT_TRUE(file.is_valid());
148 }
149
150 int count;
151 fml::FileVisitor count_visitor = [&count](const fml::UniqueFD& directory,
152 const std::string& filename) {
153 count += 1;
154 return true;
155 };
156 count = 0;
157 fml::VisitFiles(dir.fd(), count_visitor);
158 ASSERT_EQ(count, 1);
159
160 // Without `rewinddir` in `VisitFiles`, the following check would fail.
161 count = 0;
162 fml::VisitFiles(dir.fd(), count_visitor);
163 ASSERT_EQ(count, 1);
164
165 ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
166}
int count
bool VisitFiles(const fml::UniqueFD &directory, const FileVisitor &visitor)

◆ WriteStringToFile()

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

Definition at line 16 of file file_unittest.cc.

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}