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"
13 namespace filesystem
{
16 using FileImplTest
= FilesTestBase
;
18 TEST_F(FileImplTest
, CreateWriteCloseRenameOpenRead
) {
19 DirectoryPtr directory
;
20 GetTemporaryRoot(&directory
);
26 error
= FILE_ERROR_FAILED
;
27 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
29 ASSERT_TRUE(directory
.WaitForIncomingResponse());
30 EXPECT_EQ(FILE_ERROR_OK
, error
);
33 std::vector
<uint8_t> bytes_to_write
;
34 bytes_to_write
.push_back(static_cast<uint8_t>('h'));
35 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
36 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
37 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
38 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
39 error
= FILE_ERROR_FAILED
;
40 uint32_t num_bytes_written
= 0;
41 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
42 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
43 ASSERT_TRUE(file
.WaitForIncomingResponse());
44 EXPECT_EQ(FILE_ERROR_OK
, error
);
45 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
48 error
= FILE_ERROR_FAILED
;
49 file
->Close(Capture(&error
));
50 ASSERT_TRUE(file
.WaitForIncomingResponse());
51 EXPECT_EQ(FILE_ERROR_OK
, error
);
55 error
= FILE_ERROR_FAILED
;
56 directory
->Rename("my_file", "your_file", Capture(&error
));
57 ASSERT_TRUE(directory
.WaitForIncomingResponse());
58 EXPECT_EQ(FILE_ERROR_OK
, error
);
61 // Open my_file again.
63 error
= FILE_ERROR_FAILED
;
64 directory
->OpenFile("your_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
66 ASSERT_TRUE(directory
.WaitForIncomingResponse());
67 EXPECT_EQ(FILE_ERROR_OK
, error
);
70 mojo::Array
<uint8_t> bytes_read
;
71 error
= FILE_ERROR_FAILED
;
72 file
->Read(3, 1, WHENCE_FROM_BEGIN
, Capture(&error
, &bytes_read
));
73 ASSERT_TRUE(file
.WaitForIncomingResponse());
74 EXPECT_EQ(FILE_ERROR_OK
, error
);
75 ASSERT_EQ(3u, bytes_read
.size());
76 EXPECT_EQ(static_cast<uint8_t>('e'), bytes_read
[0]);
77 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read
[1]);
78 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read
[2]);
81 // TODO(vtl): Test read/write offset options.
84 TEST_F(FileImplTest
, CantWriteInReadMode
) {
85 DirectoryPtr directory
;
86 GetTemporaryRoot(&directory
);
89 std::vector
<uint8_t> bytes_to_write
;
90 bytes_to_write
.push_back(static_cast<uint8_t>('h'));
91 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
92 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
93 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
94 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
99 error
= FILE_ERROR_FAILED
;
100 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
102 ASSERT_TRUE(directory
.WaitForIncomingResponse());
103 EXPECT_EQ(FILE_ERROR_OK
, error
);
106 error
= FILE_ERROR_FAILED
;
107 uint32_t num_bytes_written
= 0;
108 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
109 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
110 ASSERT_TRUE(file
.WaitForIncomingResponse());
111 EXPECT_EQ(FILE_ERROR_OK
, error
);
112 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
115 error
= FILE_ERROR_FAILED
;
116 file
->Close(Capture(&error
));
117 ASSERT_TRUE(file
.WaitForIncomingResponse());
118 EXPECT_EQ(FILE_ERROR_OK
, error
);
122 // Open my_file again, this time with read only mode.
124 error
= FILE_ERROR_FAILED
;
125 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
127 ASSERT_TRUE(directory
.WaitForIncomingResponse());
128 EXPECT_EQ(FILE_ERROR_OK
, error
);
130 // Try to write in read mode; it should fail.
131 error
= FILE_ERROR_OK
;
132 uint32_t num_bytes_written
= 0;
133 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
134 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
136 ASSERT_TRUE(file
.WaitForIncomingResponse());
137 EXPECT_EQ(FILE_ERROR_FAILED
, error
);
138 EXPECT_EQ(0u, num_bytes_written
);
141 error
= FILE_ERROR_FAILED
;
142 file
->Close(Capture(&error
));
143 ASSERT_TRUE(file
.WaitForIncomingResponse());
144 EXPECT_EQ(FILE_ERROR_OK
, error
);
148 TEST_F(FileImplTest
, OpenInAppendMode
) {
149 DirectoryPtr directory
;
150 GetTemporaryRoot(&directory
);
156 error
= FILE_ERROR_FAILED
;
157 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
159 ASSERT_TRUE(directory
.WaitForIncomingResponse());
160 EXPECT_EQ(FILE_ERROR_OK
, error
);
163 std::vector
<uint8_t> bytes_to_write
;
164 bytes_to_write
.push_back(static_cast<uint8_t>('h'));
165 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
166 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
167 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
168 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
169 error
= FILE_ERROR_FAILED
;
170 uint32_t num_bytes_written
= 0;
171 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
172 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
173 ASSERT_TRUE(file
.WaitForIncomingResponse());
174 EXPECT_EQ(FILE_ERROR_OK
, error
);
175 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
178 error
= FILE_ERROR_FAILED
;
179 file
->Close(Capture(&error
));
180 ASSERT_TRUE(file
.WaitForIncomingResponse());
181 EXPECT_EQ(FILE_ERROR_OK
, error
);
185 // Append to my_file.
187 error
= FILE_ERROR_FAILED
;
188 directory
->OpenFile("my_file", GetProxy(&file
), kFlagAppend
| kFlagOpen
,
190 ASSERT_TRUE(directory
.WaitForIncomingResponse());
191 EXPECT_EQ(FILE_ERROR_OK
, error
);
194 std::vector
<uint8_t> bytes_to_write
;
195 bytes_to_write
.push_back(static_cast<uint8_t>('g'));
196 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
197 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
198 bytes_to_write
.push_back(static_cast<uint8_t>('d'));
199 bytes_to_write
.push_back(static_cast<uint8_t>('b'));
200 bytes_to_write
.push_back(static_cast<uint8_t>('y'));
201 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
202 error
= FILE_ERROR_FAILED
;
203 uint32_t num_bytes_written
= 0;
204 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
205 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
206 ASSERT_TRUE(file
.WaitForIncomingResponse());
207 EXPECT_EQ(FILE_ERROR_OK
, error
);
208 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
211 error
= FILE_ERROR_FAILED
;
212 file
->Close(Capture(&error
));
213 ASSERT_TRUE(file
.WaitForIncomingResponse());
214 EXPECT_EQ(FILE_ERROR_OK
, error
);
218 // Open my_file again.
220 error
= FILE_ERROR_FAILED
;
221 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
223 ASSERT_TRUE(directory
.WaitForIncomingResponse());
224 EXPECT_EQ(FILE_ERROR_OK
, error
);
227 mojo::Array
<uint8_t> bytes_read
;
228 error
= FILE_ERROR_FAILED
;
229 file
->Read(12, 0, WHENCE_FROM_BEGIN
, Capture(&error
, &bytes_read
));
230 ASSERT_TRUE(file
.WaitForIncomingResponse());
231 EXPECT_EQ(FILE_ERROR_OK
, error
);
232 ASSERT_EQ(12u, bytes_read
.size());
233 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read
[3]);
234 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read
[4]);
235 EXPECT_EQ(static_cast<uint8_t>('g'), bytes_read
[5]);
236 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read
[6]);
240 TEST_F(FileImplTest
, OpenInTruncateMode
) {
241 DirectoryPtr directory
;
242 GetTemporaryRoot(&directory
);
248 error
= FILE_ERROR_FAILED
;
249 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
251 ASSERT_TRUE(directory
.WaitForIncomingResponse());
252 EXPECT_EQ(FILE_ERROR_OK
, error
);
255 std::vector
<uint8_t> bytes_to_write
;
256 bytes_to_write
.push_back(static_cast<uint8_t>('h'));
257 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
258 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
259 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
260 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
261 error
= FILE_ERROR_FAILED
;
262 uint32_t num_bytes_written
= 0;
263 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
264 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
265 ASSERT_TRUE(file
.WaitForIncomingResponse());
266 EXPECT_EQ(FILE_ERROR_OK
, error
);
267 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
270 error
= FILE_ERROR_FAILED
;
271 file
->Close(Capture(&error
));
272 ASSERT_TRUE(file
.WaitForIncomingResponse());
273 EXPECT_EQ(FILE_ERROR_OK
, error
);
277 // Append to my_file.
279 error
= FILE_ERROR_FAILED
;
280 directory
->OpenFile("my_file", GetProxy(&file
),
281 kFlagWrite
| kFlagOpenTruncated
, Capture(&error
));
282 ASSERT_TRUE(directory
.WaitForIncomingResponse());
283 EXPECT_EQ(FILE_ERROR_OK
, error
);
286 std::vector
<uint8_t> bytes_to_write
;
287 bytes_to_write
.push_back(static_cast<uint8_t>('g'));
288 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
289 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
290 bytes_to_write
.push_back(static_cast<uint8_t>('d'));
291 bytes_to_write
.push_back(static_cast<uint8_t>('b'));
292 bytes_to_write
.push_back(static_cast<uint8_t>('y'));
293 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
294 error
= FILE_ERROR_FAILED
;
295 uint32_t num_bytes_written
= 0;
296 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
297 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
298 ASSERT_TRUE(file
.WaitForIncomingResponse());
299 EXPECT_EQ(FILE_ERROR_OK
, error
);
300 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
303 error
= FILE_ERROR_FAILED
;
304 file
->Close(Capture(&error
));
305 ASSERT_TRUE(file
.WaitForIncomingResponse());
306 EXPECT_EQ(FILE_ERROR_OK
, error
);
310 // Open my_file again.
312 error
= FILE_ERROR_FAILED
;
313 directory
->OpenFile("my_file", GetProxy(&file
), kFlagRead
| kFlagOpen
,
315 ASSERT_TRUE(directory
.WaitForIncomingResponse());
316 EXPECT_EQ(FILE_ERROR_OK
, error
);
319 mojo::Array
<uint8_t> bytes_read
;
320 error
= FILE_ERROR_FAILED
;
321 file
->Read(7, 0, WHENCE_FROM_BEGIN
, Capture(&error
, &bytes_read
));
322 ASSERT_TRUE(file
.WaitForIncomingResponse());
323 EXPECT_EQ(FILE_ERROR_OK
, error
);
324 ASSERT_EQ(7u, bytes_read
.size());
325 EXPECT_EQ(static_cast<uint8_t>('g'), bytes_read
[0]);
326 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read
[1]);
327 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read
[2]);
328 EXPECT_EQ(static_cast<uint8_t>('d'), bytes_read
[3]);
332 // Note: Ignore nanoseconds, since it may not always be supported. We expect at
333 // least second-resolution support though.
334 TEST_F(FileImplTest
, StatTouch
) {
335 DirectoryPtr directory
;
336 GetTemporaryRoot(&directory
);
341 error
= FILE_ERROR_FAILED
;
342 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
344 ASSERT_TRUE(directory
.WaitForIncomingResponse());
345 EXPECT_EQ(FILE_ERROR_OK
, error
);
348 error
= FILE_ERROR_FAILED
;
349 FileInformationPtr file_info
;
350 file
->Stat(Capture(&error
, &file_info
));
351 ASSERT_TRUE(file
.WaitForIncomingResponse());
352 EXPECT_EQ(FILE_ERROR_OK
, error
);
353 ASSERT_FALSE(file_info
.is_null());
354 EXPECT_EQ(FS_FILE_TYPE_REGULAR_FILE
, file_info
->type
);
355 EXPECT_EQ(0, file_info
->size
);
356 EXPECT_GT(file_info
->atime
, 0); // Expect that it's not 1970-01-01.
357 EXPECT_GT(file_info
->mtime
, 0);
358 double first_mtime
= file_info
->mtime
;
360 // Touch only the atime.
361 error
= FILE_ERROR_FAILED
;
362 TimespecOrNowPtr
t(TimespecOrNow::New());
364 const int64_t kPartyTime1
= 1234567890; // Party like it's 2009-02-13.
365 t
->seconds
= kPartyTime1
;
366 file
->Touch(t
.Pass(), nullptr, Capture(&error
));
367 ASSERT_TRUE(file
.WaitForIncomingResponse());
368 EXPECT_EQ(FILE_ERROR_OK
, error
);
371 error
= FILE_ERROR_FAILED
;
373 file
->Stat(Capture(&error
, &file_info
));
374 ASSERT_TRUE(file
.WaitForIncomingResponse());
375 EXPECT_EQ(FILE_ERROR_OK
, error
);
376 ASSERT_FALSE(file_info
.is_null());
377 EXPECT_EQ(kPartyTime1
, file_info
->atime
);
378 EXPECT_EQ(first_mtime
, file_info
->mtime
);
380 // Touch only the mtime.
381 t
= TimespecOrNow::New();
383 const int64_t kPartyTime2
= 1425059525; // No time like the present.
384 t
->seconds
= kPartyTime2
;
385 file
->Touch(nullptr, t
.Pass(), Capture(&error
));
386 ASSERT_TRUE(file
.WaitForIncomingResponse());
387 EXPECT_EQ(FILE_ERROR_OK
, error
);
390 error
= FILE_ERROR_FAILED
;
392 file
->Stat(Capture(&error
, &file_info
));
393 ASSERT_TRUE(file
.WaitForIncomingResponse());
394 EXPECT_EQ(FILE_ERROR_OK
, error
);
395 ASSERT_FALSE(file_info
.is_null());
396 EXPECT_EQ(kPartyTime1
, file_info
->atime
);
397 EXPECT_EQ(kPartyTime2
, file_info
->mtime
);
399 // TODO(vtl): Also test non-zero file size.
400 // TODO(vtl): Also test Touch() "now" options.
401 // TODO(vtl): Also test touching both atime and mtime.
404 TEST_F(FileImplTest
, TellSeek
) {
405 DirectoryPtr directory
;
406 GetTemporaryRoot(&directory
);
411 error
= FILE_ERROR_FAILED
;
412 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
414 ASSERT_TRUE(directory
.WaitForIncomingResponse());
415 EXPECT_EQ(FILE_ERROR_OK
, error
);
418 std::vector
<uint8_t> bytes_to_write(1000, '!');
419 error
= FILE_ERROR_FAILED
;
420 uint32_t num_bytes_written
= 0;
421 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
422 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
423 ASSERT_TRUE(file
.WaitForIncomingResponse());
424 EXPECT_EQ(FILE_ERROR_OK
, error
);
425 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
426 const int size
= static_cast<int>(num_bytes_written
);
429 error
= FILE_ERROR_FAILED
;
430 int64_t position
= -1;
431 file
->Tell(Capture(&error
, &position
));
432 ASSERT_TRUE(file
.WaitForIncomingResponse());
433 // Should be at the end.
434 EXPECT_EQ(FILE_ERROR_OK
, error
);
435 EXPECT_EQ(size
, position
);
438 error
= FILE_ERROR_FAILED
;
440 file
->Seek(-100, WHENCE_FROM_CURRENT
, Capture(&error
, &position
));
441 ASSERT_TRUE(file
.WaitForIncomingResponse());
442 EXPECT_EQ(FILE_ERROR_OK
, error
);
443 EXPECT_EQ(size
- 100, position
);
446 error
= FILE_ERROR_FAILED
;
448 file
->Tell(Capture(&error
, &position
));
449 ASSERT_TRUE(file
.WaitForIncomingResponse());
450 EXPECT_EQ(FILE_ERROR_OK
, error
);
451 EXPECT_EQ(size
- 100, position
);
453 // Seek to 123 from start.
454 error
= FILE_ERROR_FAILED
;
456 file
->Seek(123, WHENCE_FROM_BEGIN
, Capture(&error
, &position
));
457 ASSERT_TRUE(file
.WaitForIncomingResponse());
458 EXPECT_EQ(FILE_ERROR_OK
, error
);
459 EXPECT_EQ(123, position
);
462 error
= FILE_ERROR_FAILED
;
464 file
->Tell(Capture(&error
, &position
));
465 ASSERT_TRUE(file
.WaitForIncomingResponse());
466 EXPECT_EQ(FILE_ERROR_OK
, error
);
467 EXPECT_EQ(123, position
);
469 // Seek to 123 back from end.
470 error
= FILE_ERROR_FAILED
;
472 file
->Seek(-123, WHENCE_FROM_END
, Capture(&error
, &position
));
473 ASSERT_TRUE(file
.WaitForIncomingResponse());
474 EXPECT_EQ(FILE_ERROR_OK
, error
);
475 EXPECT_EQ(size
- 123, position
);
478 error
= FILE_ERROR_FAILED
;
480 file
->Tell(Capture(&error
, &position
));
481 ASSERT_TRUE(file
.WaitForIncomingResponse());
482 EXPECT_EQ(FILE_ERROR_OK
, error
);
483 EXPECT_EQ(size
- 123, position
);
485 // TODO(vtl): Check that seeking actually affects reading/writing.
486 // TODO(vtl): Check that seeking can extend the file?
489 TEST_F(FileImplTest
, Dup
) {
490 DirectoryPtr directory
;
491 GetTemporaryRoot(&directory
);
496 error
= FILE_ERROR_FAILED
;
497 directory
->OpenFile("my_file", GetProxy(&file1
),
498 kFlagRead
| kFlagWrite
| kFlagCreate
, Capture(&error
));
499 ASSERT_TRUE(directory
.WaitForIncomingResponse());
500 EXPECT_EQ(FILE_ERROR_OK
, error
);
503 std::vector
<uint8_t> bytes_to_write
;
504 bytes_to_write
.push_back(static_cast<uint8_t>('h'));
505 bytes_to_write
.push_back(static_cast<uint8_t>('e'));
506 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
507 bytes_to_write
.push_back(static_cast<uint8_t>('l'));
508 bytes_to_write
.push_back(static_cast<uint8_t>('o'));
509 error
= FILE_ERROR_FAILED
;
510 uint32_t num_bytes_written
= 0;
511 file1
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
512 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
513 ASSERT_TRUE(file1
.WaitForIncomingResponse());
514 EXPECT_EQ(FILE_ERROR_OK
, error
);
515 EXPECT_EQ(bytes_to_write
.size(), num_bytes_written
);
516 const int end_hello_pos
= static_cast<int>(num_bytes_written
);
520 error
= FILE_ERROR_FAILED
;
521 file1
->Dup(GetProxy(&file2
), Capture(&error
));
522 ASSERT_TRUE(file1
.WaitForIncomingResponse());
523 EXPECT_EQ(FILE_ERROR_OK
, error
);
525 // |file2| should have the same position.
526 error
= FILE_ERROR_FAILED
;
527 int64_t position
= -1;
528 file2
->Tell(Capture(&error
, &position
));
529 ASSERT_TRUE(file2
.WaitForIncomingResponse());
530 EXPECT_EQ(FILE_ERROR_OK
, error
);
531 EXPECT_EQ(end_hello_pos
, position
);
533 // Write using |file2|.
534 std::vector
<uint8_t> more_bytes_to_write
;
535 more_bytes_to_write
.push_back(static_cast<uint8_t>('w'));
536 more_bytes_to_write
.push_back(static_cast<uint8_t>('o'));
537 more_bytes_to_write
.push_back(static_cast<uint8_t>('r'));
538 more_bytes_to_write
.push_back(static_cast<uint8_t>('l'));
539 more_bytes_to_write
.push_back(static_cast<uint8_t>('d'));
540 error
= FILE_ERROR_FAILED
;
541 num_bytes_written
= 0;
542 file2
->Write(mojo::Array
<uint8_t>::From(more_bytes_to_write
), 0,
543 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
544 ASSERT_TRUE(file2
.WaitForIncomingResponse());
545 EXPECT_EQ(FILE_ERROR_OK
, error
);
546 EXPECT_EQ(more_bytes_to_write
.size(), num_bytes_written
);
547 const int end_world_pos
= end_hello_pos
+ static_cast<int>(num_bytes_written
);
549 // |file1| should have the same position.
550 error
= FILE_ERROR_FAILED
;
552 file1
->Tell(Capture(&error
, &position
));
553 ASSERT_TRUE(file1
.WaitForIncomingResponse());
554 EXPECT_EQ(FILE_ERROR_OK
, error
);
555 EXPECT_EQ(end_world_pos
, position
);
558 error
= FILE_ERROR_FAILED
;
559 file1
->Close(Capture(&error
));
560 ASSERT_TRUE(file1
.WaitForIncomingResponse());
561 EXPECT_EQ(FILE_ERROR_OK
, error
);
563 // Read everything using |file2|.
564 mojo::Array
<uint8_t> bytes_read
;
565 error
= FILE_ERROR_FAILED
;
566 file2
->Read(1000, 0, WHENCE_FROM_BEGIN
, Capture(&error
, &bytes_read
));
567 ASSERT_TRUE(file2
.WaitForIncomingResponse());
568 EXPECT_EQ(FILE_ERROR_OK
, error
);
569 ASSERT_EQ(static_cast<size_t>(end_world_pos
), bytes_read
.size());
570 // Just check the first and last bytes.
571 EXPECT_EQ(static_cast<uint8_t>('h'), bytes_read
[0]);
572 EXPECT_EQ(static_cast<uint8_t>('d'), bytes_read
[end_world_pos
- 1]);
574 // TODO(vtl): Test that |file2| has the same open options as |file1|.
577 TEST_F(FileImplTest
, Truncate
) {
578 const uint32_t kInitialSize
= 1000;
579 const uint32_t kTruncatedSize
= 654;
581 DirectoryPtr directory
;
582 GetTemporaryRoot(&directory
);
587 error
= FILE_ERROR_FAILED
;
588 directory
->OpenFile("my_file", GetProxy(&file
), kFlagWrite
| kFlagCreate
,
590 ASSERT_TRUE(directory
.WaitForIncomingResponse());
591 EXPECT_EQ(FILE_ERROR_OK
, error
);
594 std::vector
<uint8_t> bytes_to_write(kInitialSize
, '!');
595 error
= FILE_ERROR_FAILED
;
596 uint32_t num_bytes_written
= 0;
597 file
->Write(mojo::Array
<uint8_t>::From(bytes_to_write
), 0,
598 WHENCE_FROM_CURRENT
, Capture(&error
, &num_bytes_written
));
599 ASSERT_TRUE(file
.WaitForIncomingResponse());
600 EXPECT_EQ(FILE_ERROR_OK
, error
);
601 EXPECT_EQ(kInitialSize
, num_bytes_written
);
604 error
= FILE_ERROR_FAILED
;
605 FileInformationPtr file_info
;
606 file
->Stat(Capture(&error
, &file_info
));
607 ASSERT_TRUE(file
.WaitForIncomingResponse());
608 EXPECT_EQ(FILE_ERROR_OK
, error
);
609 ASSERT_FALSE(file_info
.is_null());
610 EXPECT_EQ(kInitialSize
, file_info
->size
);
613 error
= FILE_ERROR_FAILED
;
614 file
->Truncate(kTruncatedSize
, Capture(&error
));
615 ASSERT_TRUE(file
.WaitForIncomingResponse());
616 EXPECT_EQ(FILE_ERROR_OK
, error
);
619 error
= FILE_ERROR_FAILED
;
621 file
->Stat(Capture(&error
, &file_info
));
622 ASSERT_TRUE(file
.WaitForIncomingResponse());
623 EXPECT_EQ(FILE_ERROR_OK
, error
);
624 ASSERT_FALSE(file_info
.is_null());
625 EXPECT_EQ(kTruncatedSize
, file_info
->size
);
628 TEST_F(FileImplTest
, AsHandle
) {
629 DirectoryPtr directory
;
630 GetTemporaryRoot(&directory
);
636 error
= FILE_ERROR_FAILED
;
637 directory
->OpenFile("my_file", GetProxy(&file1
),
638 kFlagRead
| kFlagWrite
| kFlagCreate
, Capture(&error
));
639 ASSERT_TRUE(directory
.WaitForIncomingResponse());
640 EXPECT_EQ(FILE_ERROR_OK
, error
);
643 error
= FILE_ERROR_FAILED
;
644 mojo::ScopedHandle handle
;
645 file1
->AsHandle(Capture(&error
, &handle
));
646 ASSERT_TRUE(file1
.WaitForIncomingResponse());
647 EXPECT_EQ(FILE_ERROR_OK
, error
);
649 // Pull a file descriptor out of the scoped handle.
650 MojoPlatformHandle platform_handle
;
651 MojoResult extract_result
=
652 MojoExtractPlatformHandle(handle
.release().value(), &platform_handle
);
653 EXPECT_EQ(MOJO_RESULT_OK
, extract_result
);
655 // Pass this raw file descriptor to a base::File.
656 base::File
raw_file(platform_handle
);
657 ASSERT_TRUE(raw_file
.IsValid());
658 EXPECT_EQ(5, raw_file
.WriteAtCurrentPos("hello", 5));
664 error
= FILE_ERROR_FAILED
;
665 directory
->OpenFile("my_file", GetProxy(&file2
), kFlagRead
| kFlagOpen
,
667 ASSERT_TRUE(directory
.WaitForIncomingResponse());
668 EXPECT_EQ(FILE_ERROR_OK
, error
);
670 // Verify that we wrote data raw on the file descriptor.
671 mojo::Array
<uint8_t> bytes_read
;
672 error
= FILE_ERROR_FAILED
;
673 file2
->Read(5, 0, WHENCE_FROM_BEGIN
, Capture(&error
, &bytes_read
));
674 ASSERT_TRUE(file2
.WaitForIncomingResponse());
675 EXPECT_EQ(FILE_ERROR_OK
, error
);
676 ASSERT_EQ(5u, bytes_read
.size());
677 EXPECT_EQ(static_cast<uint8_t>('h'), bytes_read
[0]);
678 EXPECT_EQ(static_cast<uint8_t>('e'), bytes_read
[1]);
679 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read
[2]);
680 EXPECT_EQ(static_cast<uint8_t>('l'), bytes_read
[3]);
681 EXPECT_EQ(static_cast<uint8_t>('o'), bytes_read
[4]);
686 } // namespace filesystem