Roll src/third_party/WebKit 605a979:06cb9e9 (svn 202556:202558)
[chromium-blink-merge.git] / components / filesystem / file_impl_unittest.cc
blob86ec3edac8afa43a4f2dea0e97e6dfda6345cd2c
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <vector>
7 #include "base/files/file.h"
8 #include "components/filesystem/files_test_base.h"
9 #include "mojo/platform_handle/platform_handle_functions.h"
10 #include "mojo/public/cpp/bindings/interface_request.h"
11 #include "mojo/public/cpp/bindings/type_converter.h"
12 #include "mojo/util/capture_util.h"
14 using mojo::Capture;
16 namespace filesystem {
17 namespace {
19 using FileImplTest = FilesTestBase;
21 TEST_F(FileImplTest, CreateWriteCloseRenameOpenRead) {
22 DirectoryPtr directory;
23 GetTemporaryRoot(&directory);
24 FileError error;
27 // Create my_file.
28 FilePtr file;
29 error = FILE_ERROR_FAILED;
30 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
31 Capture(&error));
32 ASSERT_TRUE(directory.WaitForIncomingResponse());
33 EXPECT_EQ(FILE_ERROR_OK, error);
35 // Write to it.
36 std::vector<uint8_t> bytes_to_write;
37 bytes_to_write.push_back(static_cast<uint8_t>('h'));
38 bytes_to_write.push_back(static_cast<uint8_t>('e'));
39 bytes_to_write.push_back(static_cast<uint8_t>('l'));
40 bytes_to_write.push_back(static_cast<uint8_t>('l'));
41 bytes_to_write.push_back(static_cast<uint8_t>('o'));
42 error = FILE_ERROR_FAILED;
43 uint32_t num_bytes_written = 0;
44 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
45 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
46 ASSERT_TRUE(file.WaitForIncomingResponse());
47 EXPECT_EQ(FILE_ERROR_OK, error);
48 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
50 // Close it.
51 error = FILE_ERROR_FAILED;
52 file->Close(Capture(&error));
53 ASSERT_TRUE(file.WaitForIncomingResponse());
54 EXPECT_EQ(FILE_ERROR_OK, error);
57 // Rename it.
58 error = FILE_ERROR_FAILED;
59 directory->Rename("my_file", "your_file", Capture(&error));
60 ASSERT_TRUE(directory.WaitForIncomingResponse());
61 EXPECT_EQ(FILE_ERROR_OK, error);
64 // Open my_file again.
65 FilePtr file;
66 error = FILE_ERROR_FAILED;
67 directory->OpenFile("your_file", GetProxy(&file), kFlagRead | kFlagOpen,
68 Capture(&error));
69 ASSERT_TRUE(directory.WaitForIncomingResponse());
70 EXPECT_EQ(FILE_ERROR_OK, error);
72 // Read from it.
73 mojo::Array<uint8_t> bytes_read;
74 error = FILE_ERROR_FAILED;
75 file->Read(3, 1, WHENCE_FROM_BEGIN, Capture(&error, &bytes_read));
76 ASSERT_TRUE(file.WaitForIncomingResponse());
77 EXPECT_EQ(FILE_ERROR_OK, error);
78 ASSERT_EQ(3u, bytes_read.size());
79 EXPECT_EQ(static_cast<uint8_t>('e'), bytes_read[0]);
80 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[1]);
81 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[2]);
84 // TODO(vtl): Test read/write offset options.
87 TEST_F(FileImplTest, CantWriteInReadMode) {
88 DirectoryPtr directory;
89 GetTemporaryRoot(&directory);
90 FileError error;
92 std::vector<uint8_t> bytes_to_write;
93 bytes_to_write.push_back(static_cast<uint8_t>('h'));
94 bytes_to_write.push_back(static_cast<uint8_t>('e'));
95 bytes_to_write.push_back(static_cast<uint8_t>('l'));
96 bytes_to_write.push_back(static_cast<uint8_t>('l'));
97 bytes_to_write.push_back(static_cast<uint8_t>('o'));
100 // Create my_file.
101 FilePtr file;
102 error = FILE_ERROR_FAILED;
103 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
104 Capture(&error));
105 ASSERT_TRUE(directory.WaitForIncomingResponse());
106 EXPECT_EQ(FILE_ERROR_OK, error);
108 // Write to it.
109 error = FILE_ERROR_FAILED;
110 uint32_t num_bytes_written = 0;
111 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
112 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
113 ASSERT_TRUE(file.WaitForIncomingResponse());
114 EXPECT_EQ(FILE_ERROR_OK, error);
115 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
117 // Close it.
118 error = FILE_ERROR_FAILED;
119 file->Close(Capture(&error));
120 ASSERT_TRUE(file.WaitForIncomingResponse());
121 EXPECT_EQ(FILE_ERROR_OK, error);
125 // Open my_file again, this time with read only mode.
126 FilePtr file;
127 error = FILE_ERROR_FAILED;
128 directory->OpenFile("my_file", GetProxy(&file), kFlagRead | kFlagOpen,
129 Capture(&error));
130 ASSERT_TRUE(directory.WaitForIncomingResponse());
131 EXPECT_EQ(FILE_ERROR_OK, error);
133 // Try to write in read mode; it should fail.
134 error = FILE_ERROR_OK;
135 uint32_t num_bytes_written = 0;
136 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
137 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
139 ASSERT_TRUE(file.WaitForIncomingResponse());
140 EXPECT_EQ(FILE_ERROR_FAILED, error);
141 EXPECT_EQ(0u, num_bytes_written);
143 // Close it.
144 error = FILE_ERROR_FAILED;
145 file->Close(Capture(&error));
146 ASSERT_TRUE(file.WaitForIncomingResponse());
147 EXPECT_EQ(FILE_ERROR_OK, error);
151 TEST_F(FileImplTest, OpenInAppendMode) {
152 DirectoryPtr directory;
153 GetTemporaryRoot(&directory);
154 FileError error;
157 // Create my_file.
158 FilePtr file;
159 error = FILE_ERROR_FAILED;
160 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
161 Capture(&error));
162 ASSERT_TRUE(directory.WaitForIncomingResponse());
163 EXPECT_EQ(FILE_ERROR_OK, error);
165 // Write to it.
166 std::vector<uint8_t> bytes_to_write;
167 bytes_to_write.push_back(static_cast<uint8_t>('h'));
168 bytes_to_write.push_back(static_cast<uint8_t>('e'));
169 bytes_to_write.push_back(static_cast<uint8_t>('l'));
170 bytes_to_write.push_back(static_cast<uint8_t>('l'));
171 bytes_to_write.push_back(static_cast<uint8_t>('o'));
172 error = FILE_ERROR_FAILED;
173 uint32_t num_bytes_written = 0;
174 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
175 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
176 ASSERT_TRUE(file.WaitForIncomingResponse());
177 EXPECT_EQ(FILE_ERROR_OK, error);
178 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
180 // Close it.
181 error = FILE_ERROR_FAILED;
182 file->Close(Capture(&error));
183 ASSERT_TRUE(file.WaitForIncomingResponse());
184 EXPECT_EQ(FILE_ERROR_OK, error);
188 // Append to my_file.
189 FilePtr file;
190 error = FILE_ERROR_FAILED;
191 directory->OpenFile("my_file", GetProxy(&file), kFlagAppend | kFlagOpen,
192 Capture(&error));
193 ASSERT_TRUE(directory.WaitForIncomingResponse());
194 EXPECT_EQ(FILE_ERROR_OK, error);
196 // Write to it.
197 std::vector<uint8_t> bytes_to_write;
198 bytes_to_write.push_back(static_cast<uint8_t>('g'));
199 bytes_to_write.push_back(static_cast<uint8_t>('o'));
200 bytes_to_write.push_back(static_cast<uint8_t>('o'));
201 bytes_to_write.push_back(static_cast<uint8_t>('d'));
202 bytes_to_write.push_back(static_cast<uint8_t>('b'));
203 bytes_to_write.push_back(static_cast<uint8_t>('y'));
204 bytes_to_write.push_back(static_cast<uint8_t>('e'));
205 error = FILE_ERROR_FAILED;
206 uint32_t num_bytes_written = 0;
207 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
208 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
209 ASSERT_TRUE(file.WaitForIncomingResponse());
210 EXPECT_EQ(FILE_ERROR_OK, error);
211 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
213 // Close it.
214 error = FILE_ERROR_FAILED;
215 file->Close(Capture(&error));
216 ASSERT_TRUE(file.WaitForIncomingResponse());
217 EXPECT_EQ(FILE_ERROR_OK, error);
221 // Open my_file again.
222 FilePtr file;
223 error = FILE_ERROR_FAILED;
224 directory->OpenFile("my_file", GetProxy(&file), kFlagRead | kFlagOpen,
225 Capture(&error));
226 ASSERT_TRUE(directory.WaitForIncomingResponse());
227 EXPECT_EQ(FILE_ERROR_OK, error);
229 // Read from it.
230 mojo::Array<uint8_t> bytes_read;
231 error = FILE_ERROR_FAILED;
232 file->Read(12, 0, WHENCE_FROM_BEGIN, Capture(&error, &bytes_read));
233 ASSERT_TRUE(file.WaitForIncomingResponse());
234 EXPECT_EQ(FILE_ERROR_OK, error);
235 ASSERT_EQ(12u, bytes_read.size());
236 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[3]);
237 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read[4]);
238 EXPECT_EQ(static_cast<uint8_t>('g'), bytes_read[5]);
239 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read[6]);
243 TEST_F(FileImplTest, OpenInTruncateMode) {
244 DirectoryPtr directory;
245 GetTemporaryRoot(&directory);
246 FileError error;
249 // Create my_file.
250 FilePtr file;
251 error = FILE_ERROR_FAILED;
252 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
253 Capture(&error));
254 ASSERT_TRUE(directory.WaitForIncomingResponse());
255 EXPECT_EQ(FILE_ERROR_OK, error);
257 // Write to it.
258 std::vector<uint8_t> bytes_to_write;
259 bytes_to_write.push_back(static_cast<uint8_t>('h'));
260 bytes_to_write.push_back(static_cast<uint8_t>('e'));
261 bytes_to_write.push_back(static_cast<uint8_t>('l'));
262 bytes_to_write.push_back(static_cast<uint8_t>('l'));
263 bytes_to_write.push_back(static_cast<uint8_t>('o'));
264 error = FILE_ERROR_FAILED;
265 uint32_t num_bytes_written = 0;
266 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
267 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
268 ASSERT_TRUE(file.WaitForIncomingResponse());
269 EXPECT_EQ(FILE_ERROR_OK, error);
270 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
272 // Close it.
273 error = FILE_ERROR_FAILED;
274 file->Close(Capture(&error));
275 ASSERT_TRUE(file.WaitForIncomingResponse());
276 EXPECT_EQ(FILE_ERROR_OK, error);
280 // Append to my_file.
281 FilePtr file;
282 error = FILE_ERROR_FAILED;
283 directory->OpenFile("my_file", GetProxy(&file),
284 kFlagWrite | kFlagOpenTruncated, Capture(&error));
285 ASSERT_TRUE(directory.WaitForIncomingResponse());
286 EXPECT_EQ(FILE_ERROR_OK, error);
288 // Write to it.
289 std::vector<uint8_t> bytes_to_write;
290 bytes_to_write.push_back(static_cast<uint8_t>('g'));
291 bytes_to_write.push_back(static_cast<uint8_t>('o'));
292 bytes_to_write.push_back(static_cast<uint8_t>('o'));
293 bytes_to_write.push_back(static_cast<uint8_t>('d'));
294 bytes_to_write.push_back(static_cast<uint8_t>('b'));
295 bytes_to_write.push_back(static_cast<uint8_t>('y'));
296 bytes_to_write.push_back(static_cast<uint8_t>('e'));
297 error = FILE_ERROR_FAILED;
298 uint32_t num_bytes_written = 0;
299 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
300 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
301 ASSERT_TRUE(file.WaitForIncomingResponse());
302 EXPECT_EQ(FILE_ERROR_OK, error);
303 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
305 // Close it.
306 error = FILE_ERROR_FAILED;
307 file->Close(Capture(&error));
308 ASSERT_TRUE(file.WaitForIncomingResponse());
309 EXPECT_EQ(FILE_ERROR_OK, error);
313 // Open my_file again.
314 FilePtr file;
315 error = FILE_ERROR_FAILED;
316 directory->OpenFile("my_file", GetProxy(&file), kFlagRead | kFlagOpen,
317 Capture(&error));
318 ASSERT_TRUE(directory.WaitForIncomingResponse());
319 EXPECT_EQ(FILE_ERROR_OK, error);
321 // Read from it.
322 mojo::Array<uint8_t> bytes_read;
323 error = FILE_ERROR_FAILED;
324 file->Read(7, 0, WHENCE_FROM_BEGIN, Capture(&error, &bytes_read));
325 ASSERT_TRUE(file.WaitForIncomingResponse());
326 EXPECT_EQ(FILE_ERROR_OK, error);
327 ASSERT_EQ(7u, bytes_read.size());
328 EXPECT_EQ(static_cast<uint8_t>('g'), bytes_read[0]);
329 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read[1]);
330 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read[2]);
331 EXPECT_EQ(static_cast<uint8_t>('d'), bytes_read[3]);
335 // Note: Ignore nanoseconds, since it may not always be supported. We expect at
336 // least second-resolution support though.
337 TEST_F(FileImplTest, StatTouch) {
338 DirectoryPtr directory;
339 GetTemporaryRoot(&directory);
340 FileError error;
342 // Create my_file.
343 FilePtr file;
344 error = FILE_ERROR_FAILED;
345 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
346 Capture(&error));
347 ASSERT_TRUE(directory.WaitForIncomingResponse());
348 EXPECT_EQ(FILE_ERROR_OK, error);
350 // Stat it.
351 error = FILE_ERROR_FAILED;
352 FileInformationPtr file_info;
353 file->Stat(Capture(&error, &file_info));
354 ASSERT_TRUE(file.WaitForIncomingResponse());
355 EXPECT_EQ(FILE_ERROR_OK, error);
356 ASSERT_FALSE(file_info.is_null());
357 EXPECT_EQ(FS_FILE_TYPE_REGULAR_FILE, file_info->type);
358 EXPECT_EQ(0, file_info->size);
359 EXPECT_GT(file_info->atime, 0); // Expect that it's not 1970-01-01.
360 EXPECT_GT(file_info->mtime, 0);
361 double first_mtime = file_info->mtime;
363 // Touch only the atime.
364 error = FILE_ERROR_FAILED;
365 TimespecOrNowPtr t(TimespecOrNow::New());
366 t->now = false;
367 const int64_t kPartyTime1 = 1234567890; // Party like it's 2009-02-13.
368 t->seconds = kPartyTime1;
369 file->Touch(t.Pass(), nullptr, Capture(&error));
370 ASSERT_TRUE(file.WaitForIncomingResponse());
371 EXPECT_EQ(FILE_ERROR_OK, error);
373 // Stat again.
374 error = FILE_ERROR_FAILED;
375 file_info.reset();
376 file->Stat(Capture(&error, &file_info));
377 ASSERT_TRUE(file.WaitForIncomingResponse());
378 EXPECT_EQ(FILE_ERROR_OK, error);
379 ASSERT_FALSE(file_info.is_null());
380 EXPECT_EQ(kPartyTime1, file_info->atime);
381 EXPECT_EQ(first_mtime, file_info->mtime);
383 // Touch only the mtime.
384 t = TimespecOrNow::New();
385 t->now = false;
386 const int64_t kPartyTime2 = 1425059525; // No time like the present.
387 t->seconds = kPartyTime2;
388 file->Touch(nullptr, t.Pass(), Capture(&error));
389 ASSERT_TRUE(file.WaitForIncomingResponse());
390 EXPECT_EQ(FILE_ERROR_OK, error);
392 // Stat again.
393 error = FILE_ERROR_FAILED;
394 file_info.reset();
395 file->Stat(Capture(&error, &file_info));
396 ASSERT_TRUE(file.WaitForIncomingResponse());
397 EXPECT_EQ(FILE_ERROR_OK, error);
398 ASSERT_FALSE(file_info.is_null());
399 EXPECT_EQ(kPartyTime1, file_info->atime);
400 EXPECT_EQ(kPartyTime2, file_info->mtime);
402 // TODO(vtl): Also test non-zero file size.
403 // TODO(vtl): Also test Touch() "now" options.
404 // TODO(vtl): Also test touching both atime and mtime.
407 TEST_F(FileImplTest, TellSeek) {
408 DirectoryPtr directory;
409 GetTemporaryRoot(&directory);
410 FileError error;
412 // Create my_file.
413 FilePtr file;
414 error = FILE_ERROR_FAILED;
415 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
416 Capture(&error));
417 ASSERT_TRUE(directory.WaitForIncomingResponse());
418 EXPECT_EQ(FILE_ERROR_OK, error);
420 // Write to it.
421 std::vector<uint8_t> bytes_to_write(1000, '!');
422 error = FILE_ERROR_FAILED;
423 uint32_t num_bytes_written = 0;
424 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
425 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
426 ASSERT_TRUE(file.WaitForIncomingResponse());
427 EXPECT_EQ(FILE_ERROR_OK, error);
428 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
429 const int size = static_cast<int>(num_bytes_written);
431 // Tell.
432 error = FILE_ERROR_FAILED;
433 int64_t position = -1;
434 file->Tell(Capture(&error, &position));
435 ASSERT_TRUE(file.WaitForIncomingResponse());
436 // Should be at the end.
437 EXPECT_EQ(FILE_ERROR_OK, error);
438 EXPECT_EQ(size, position);
440 // Seek back 100.
441 error = FILE_ERROR_FAILED;
442 position = -1;
443 file->Seek(-100, WHENCE_FROM_CURRENT, Capture(&error, &position));
444 ASSERT_TRUE(file.WaitForIncomingResponse());
445 EXPECT_EQ(FILE_ERROR_OK, error);
446 EXPECT_EQ(size - 100, position);
448 // Tell.
449 error = FILE_ERROR_FAILED;
450 position = -1;
451 file->Tell(Capture(&error, &position));
452 ASSERT_TRUE(file.WaitForIncomingResponse());
453 EXPECT_EQ(FILE_ERROR_OK, error);
454 EXPECT_EQ(size - 100, position);
456 // Seek to 123 from start.
457 error = FILE_ERROR_FAILED;
458 position = -1;
459 file->Seek(123, WHENCE_FROM_BEGIN, Capture(&error, &position));
460 ASSERT_TRUE(file.WaitForIncomingResponse());
461 EXPECT_EQ(FILE_ERROR_OK, error);
462 EXPECT_EQ(123, position);
464 // Tell.
465 error = FILE_ERROR_FAILED;
466 position = -1;
467 file->Tell(Capture(&error, &position));
468 ASSERT_TRUE(file.WaitForIncomingResponse());
469 EXPECT_EQ(FILE_ERROR_OK, error);
470 EXPECT_EQ(123, position);
472 // Seek to 123 back from end.
473 error = FILE_ERROR_FAILED;
474 position = -1;
475 file->Seek(-123, WHENCE_FROM_END, Capture(&error, &position));
476 ASSERT_TRUE(file.WaitForIncomingResponse());
477 EXPECT_EQ(FILE_ERROR_OK, error);
478 EXPECT_EQ(size - 123, position);
480 // Tell.
481 error = FILE_ERROR_FAILED;
482 position = -1;
483 file->Tell(Capture(&error, &position));
484 ASSERT_TRUE(file.WaitForIncomingResponse());
485 EXPECT_EQ(FILE_ERROR_OK, error);
486 EXPECT_EQ(size - 123, position);
488 // TODO(vtl): Check that seeking actually affects reading/writing.
489 // TODO(vtl): Check that seeking can extend the file?
492 TEST_F(FileImplTest, Dup) {
493 DirectoryPtr directory;
494 GetTemporaryRoot(&directory);
495 FileError error;
497 // Create my_file.
498 FilePtr file1;
499 error = FILE_ERROR_FAILED;
500 directory->OpenFile("my_file", GetProxy(&file1),
501 kFlagRead | kFlagWrite | kFlagCreate, Capture(&error));
502 ASSERT_TRUE(directory.WaitForIncomingResponse());
503 EXPECT_EQ(FILE_ERROR_OK, error);
505 // Write to it.
506 std::vector<uint8_t> bytes_to_write;
507 bytes_to_write.push_back(static_cast<uint8_t>('h'));
508 bytes_to_write.push_back(static_cast<uint8_t>('e'));
509 bytes_to_write.push_back(static_cast<uint8_t>('l'));
510 bytes_to_write.push_back(static_cast<uint8_t>('l'));
511 bytes_to_write.push_back(static_cast<uint8_t>('o'));
512 error = FILE_ERROR_FAILED;
513 uint32_t num_bytes_written = 0;
514 file1->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
515 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
516 ASSERT_TRUE(file1.WaitForIncomingResponse());
517 EXPECT_EQ(FILE_ERROR_OK, error);
518 EXPECT_EQ(bytes_to_write.size(), num_bytes_written);
519 const int end_hello_pos = static_cast<int>(num_bytes_written);
521 // Dup it.
522 FilePtr file2;
523 error = FILE_ERROR_FAILED;
524 file1->Dup(GetProxy(&file2), Capture(&error));
525 ASSERT_TRUE(file1.WaitForIncomingResponse());
526 EXPECT_EQ(FILE_ERROR_OK, error);
528 // |file2| should have the same position.
529 error = FILE_ERROR_FAILED;
530 int64_t position = -1;
531 file2->Tell(Capture(&error, &position));
532 ASSERT_TRUE(file2.WaitForIncomingResponse());
533 EXPECT_EQ(FILE_ERROR_OK, error);
534 EXPECT_EQ(end_hello_pos, position);
536 // Write using |file2|.
537 std::vector<uint8_t> more_bytes_to_write;
538 more_bytes_to_write.push_back(static_cast<uint8_t>('w'));
539 more_bytes_to_write.push_back(static_cast<uint8_t>('o'));
540 more_bytes_to_write.push_back(static_cast<uint8_t>('r'));
541 more_bytes_to_write.push_back(static_cast<uint8_t>('l'));
542 more_bytes_to_write.push_back(static_cast<uint8_t>('d'));
543 error = FILE_ERROR_FAILED;
544 num_bytes_written = 0;
545 file2->Write(mojo::Array<uint8_t>::From(more_bytes_to_write), 0,
546 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
547 ASSERT_TRUE(file2.WaitForIncomingResponse());
548 EXPECT_EQ(FILE_ERROR_OK, error);
549 EXPECT_EQ(more_bytes_to_write.size(), num_bytes_written);
550 const int end_world_pos = end_hello_pos + static_cast<int>(num_bytes_written);
552 // |file1| should have the same position.
553 error = FILE_ERROR_FAILED;
554 position = -1;
555 file1->Tell(Capture(&error, &position));
556 ASSERT_TRUE(file1.WaitForIncomingResponse());
557 EXPECT_EQ(FILE_ERROR_OK, error);
558 EXPECT_EQ(end_world_pos, position);
560 // Close |file1|.
561 error = FILE_ERROR_FAILED;
562 file1->Close(Capture(&error));
563 ASSERT_TRUE(file1.WaitForIncomingResponse());
564 EXPECT_EQ(FILE_ERROR_OK, error);
566 // Read everything using |file2|.
567 mojo::Array<uint8_t> bytes_read;
568 error = FILE_ERROR_FAILED;
569 file2->Read(1000, 0, WHENCE_FROM_BEGIN, Capture(&error, &bytes_read));
570 ASSERT_TRUE(file2.WaitForIncomingResponse());
571 EXPECT_EQ(FILE_ERROR_OK, error);
572 ASSERT_EQ(static_cast<size_t>(end_world_pos), bytes_read.size());
573 // Just check the first and last bytes.
574 EXPECT_EQ(static_cast<uint8_t>('h'), bytes_read[0]);
575 EXPECT_EQ(static_cast<uint8_t>('d'), bytes_read[end_world_pos - 1]);
577 // TODO(vtl): Test that |file2| has the same open options as |file1|.
580 TEST_F(FileImplTest, Truncate) {
581 const uint32_t kInitialSize = 1000;
582 const uint32_t kTruncatedSize = 654;
584 DirectoryPtr directory;
585 GetTemporaryRoot(&directory);
586 FileError error;
588 // Create my_file.
589 FilePtr file;
590 error = FILE_ERROR_FAILED;
591 directory->OpenFile("my_file", GetProxy(&file), kFlagWrite | kFlagCreate,
592 Capture(&error));
593 ASSERT_TRUE(directory.WaitForIncomingResponse());
594 EXPECT_EQ(FILE_ERROR_OK, error);
596 // Write to it.
597 std::vector<uint8_t> bytes_to_write(kInitialSize, '!');
598 error = FILE_ERROR_FAILED;
599 uint32_t num_bytes_written = 0;
600 file->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0,
601 WHENCE_FROM_CURRENT, Capture(&error, &num_bytes_written));
602 ASSERT_TRUE(file.WaitForIncomingResponse());
603 EXPECT_EQ(FILE_ERROR_OK, error);
604 EXPECT_EQ(kInitialSize, num_bytes_written);
606 // Stat it.
607 error = FILE_ERROR_FAILED;
608 FileInformationPtr file_info;
609 file->Stat(Capture(&error, &file_info));
610 ASSERT_TRUE(file.WaitForIncomingResponse());
611 EXPECT_EQ(FILE_ERROR_OK, error);
612 ASSERT_FALSE(file_info.is_null());
613 EXPECT_EQ(kInitialSize, file_info->size);
615 // Truncate it.
616 error = FILE_ERROR_FAILED;
617 file->Truncate(kTruncatedSize, Capture(&error));
618 ASSERT_TRUE(file.WaitForIncomingResponse());
619 EXPECT_EQ(FILE_ERROR_OK, error);
621 // Stat again.
622 error = FILE_ERROR_FAILED;
623 file_info.reset();
624 file->Stat(Capture(&error, &file_info));
625 ASSERT_TRUE(file.WaitForIncomingResponse());
626 EXPECT_EQ(FILE_ERROR_OK, error);
627 ASSERT_FALSE(file_info.is_null());
628 EXPECT_EQ(kTruncatedSize, file_info->size);
631 TEST_F(FileImplTest, AsHandle) {
632 DirectoryPtr directory;
633 GetTemporaryRoot(&directory);
634 FileError error;
637 // Create my_file.
638 FilePtr file1;
639 error = FILE_ERROR_FAILED;
640 directory->OpenFile("my_file", GetProxy(&file1),
641 kFlagRead | kFlagWrite | kFlagCreate, Capture(&error));
642 ASSERT_TRUE(directory.WaitForIncomingResponse());
643 EXPECT_EQ(FILE_ERROR_OK, error);
645 // Fetch the handle
646 error = FILE_ERROR_FAILED;
647 mojo::ScopedHandle handle;
648 file1->AsHandle(Capture(&error, &handle));
649 ASSERT_TRUE(file1.WaitForIncomingResponse());
650 EXPECT_EQ(FILE_ERROR_OK, error);
652 // Pull a file descriptor out of the scoped handle.
653 MojoPlatformHandle platform_handle;
654 MojoResult extract_result =
655 MojoExtractPlatformHandle(handle.release().value(), &platform_handle);
656 EXPECT_EQ(MOJO_RESULT_OK, extract_result);
658 // Pass this raw file descriptor to a base::File.
659 base::File raw_file(platform_handle);
660 ASSERT_TRUE(raw_file.IsValid());
661 EXPECT_EQ(5, raw_file.WriteAtCurrentPos("hello", 5));
665 // Reopen my_file.
666 FilePtr file2;
667 error = FILE_ERROR_FAILED;
668 directory->OpenFile("my_file", GetProxy(&file2), kFlagRead | kFlagOpen,
669 Capture(&error));
670 ASSERT_TRUE(directory.WaitForIncomingResponse());
671 EXPECT_EQ(FILE_ERROR_OK, error);
673 // Verify that we wrote data raw on the file descriptor.
674 mojo::Array<uint8_t> bytes_read;
675 error = FILE_ERROR_FAILED;
676 file2->Read(5, 0, WHENCE_FROM_BEGIN, Capture(&error, &bytes_read));
677 ASSERT_TRUE(file2.WaitForIncomingResponse());
678 EXPECT_EQ(FILE_ERROR_OK, error);
679 ASSERT_EQ(5u, bytes_read.size());
680 EXPECT_EQ(static_cast<uint8_t>('h'), bytes_read[0]);
681 EXPECT_EQ(static_cast<uint8_t>('e'), bytes_read[1]);
682 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[2]);
683 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read[3]);
684 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read[4]);
688 } // namespace
689 } // namespace filesystem