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.
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"
16 namespace filesystem
{
19 using FileImplTest
= FilesTestBase
;
21 TEST_F(FileImplTest
, CreateWriteCloseRenameOpenRead
) {
22 DirectoryPtr directory
;
23 GetTemporaryRoot(&directory
);
29 error
= FILE_ERROR_FAILED
;
30 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
32 ASSERT_TRUE(directory
.WaitForIncomingResponse());
33 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
51 error
= FILE_ERROR_FAILED
;
52 file
->Close(Capture(&error
));
53 ASSERT_TRUE(file
.WaitForIncomingResponse());
54 EXPECT_EQ(FILE_ERROR_OK
, error
);
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.
66 error
= FILE_ERROR_FAILED
;
67 directory
->OpenFile("your_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
69 ASSERT_TRUE(directory
.WaitForIncomingResponse());
70 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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'));
102 error
= FILE_ERROR_FAILED
;
103 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
105 ASSERT_TRUE(directory
.WaitForIncomingResponse());
106 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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.
127 error
= FILE_ERROR_FAILED
;
128 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
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
);
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
);
159 error
= FILE_ERROR_FAILED
;
160 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
162 ASSERT_TRUE(directory
.WaitForIncomingResponse());
163 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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.
190 error
= FILE_ERROR_FAILED
;
191 directory
->OpenFile("my_file", GetProxy(&file
), kFlagAppend
| kFlagOpen
,
193 ASSERT_TRUE(directory
.WaitForIncomingResponse());
194 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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.
223 error
= FILE_ERROR_FAILED
;
224 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
226 ASSERT_TRUE(directory
.WaitForIncomingResponse());
227 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
251 error
= FILE_ERROR_FAILED
;
252 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
254 ASSERT_TRUE(directory
.WaitForIncomingResponse());
255 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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.
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
);
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
);
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.
315 error
= FILE_ERROR_FAILED
;
316 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
318 ASSERT_TRUE(directory
.WaitForIncomingResponse());
319 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
344 error
= FILE_ERROR_FAILED
;
345 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
347 ASSERT_TRUE(directory
.WaitForIncomingResponse());
348 EXPECT_EQ(FILE_ERROR_OK
, error
);
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());
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
);
374 error
= FILE_ERROR_FAILED
;
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();
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
);
393 error
= FILE_ERROR_FAILED
;
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
);
414 error
= FILE_ERROR_FAILED
;
415 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
417 ASSERT_TRUE(directory
.WaitForIncomingResponse());
418 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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
);
441 error
= FILE_ERROR_FAILED
;
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
);
449 error
= FILE_ERROR_FAILED
;
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
;
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
);
465 error
= FILE_ERROR_FAILED
;
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
;
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
);
481 error
= FILE_ERROR_FAILED
;
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
);
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
);
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
);
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
;
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
);
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
);
590 error
= FILE_ERROR_FAILED
;
591 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
593 ASSERT_TRUE(directory
.WaitForIncomingResponse());
594 EXPECT_EQ(FILE_ERROR_OK
, error
);
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
);
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
);
616 error
= FILE_ERROR_FAILED
;
617 file
->Truncate(kTruncatedSize
, Capture(&error
));
618 ASSERT_TRUE(file
.WaitForIncomingResponse());
619 EXPECT_EQ(FILE_ERROR_OK
, error
);
622 error
= FILE_ERROR_FAILED
;
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
);
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
);
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));
667 error
= FILE_ERROR_FAILED
;
668 directory
->OpenFile("my_file", GetProxy(&file2
), kFlagRead
| kFlagOpen
,
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]);
689 } // namespace filesystem