1 // Copyright (c) 2011 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.
6 #include "base/message_loop.h"
7 #include "base/platform_file.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "webkit/chromeos/fileapi/memory_file_util.h"
13 const base::FilePath::CharType kRootPath
[] = "/mnt/memory";
14 const char kTestString
[] = "A test string. A test string.";
15 const char kTestStringLength
= arraysize(kTestString
) - 1;
20 // This test is actually testing MemoryFileUtil — an async in-memory file
21 // system, based on FileUtilAsync.
22 class MemoryFileUtilTest
: public testing::Test
{
24 MemoryFileUtilTest() : max_request_id_(0) {
27 ~MemoryFileUtilTest() {
28 for (std::map
<int, CallbackStatus
>::iterator iter
= status_map_
.begin();
29 iter
!= status_map_
.end();
31 delete iter
->second
.file_stream
;
36 file_util_
.reset(new MemoryFileUtil(base::FilePath(kRootPath
)));
39 MemoryFileUtil
* file_util() {
40 return file_util_
.get();
46 CALLBACK_TYPE_GET_FILE_INFO
,
48 CALLBACK_TYPE_READ_WRITE
,
49 CALLBACK_TYPE_READ_DIRECTORY
52 struct CallbackStatus
{
54 : type(CALLBACK_TYPE_ERROR
),
55 result(base::PLATFORM_FILE_OK
),
59 called_after_completed(false),
63 base::PlatformFileError result
;
64 base::PlatformFileInfo file_info
;
65 // This object should be deleted in the test code.
66 AsyncFileStream
* file_stream
;
69 // Following 4 fields only for ReadDirectory.
70 FileUtilAsync::FileList entries
;
72 bool called_after_completed
;
76 FileUtilAsync::StatusCallback
GetStatusCallback(int request_id
) {
77 return base::Bind(&MemoryFileUtilTest::StatusCallbackImpl
,
78 base::Unretained(this),
82 FileUtilAsync::GetFileInfoCallback
GetGetFileInfoCallback(
84 return base::Bind(&MemoryFileUtilTest::GetFileInfoCallback
,
85 base::Unretained(this),
89 FileUtilAsync::OpenCallback
GetOpenCallback(int request_id
) {
90 return base::Bind(&MemoryFileUtilTest::OpenCallback
,
91 base::Unretained(this),
95 AsyncFileStream::ReadWriteCallback
GetReadWriteCallback(int request_id
) {
96 return base::Bind(&MemoryFileUtilTest::ReadWriteCallbackImpl
,
97 base::Unretained(this),
101 FileUtilAsync::ReadDirectoryCallback
GetReadDirectoryCallback(
103 return base::Bind(&MemoryFileUtilTest::ReadDirectoryCallback
,
104 base::Unretained(this),
108 int CreateEmptyFile(const base::FilePath
& file_path
) {
109 int request_id
= GetNextRequestId();
110 file_util_
->Create(file_path
, GetStatusCallback(request_id
));
114 int CreateNonEmptyFile(const base::FilePath
& file_path
,
117 int request_id
= GetNextRequestId();
120 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
121 base::Bind(&MemoryFileUtilTest::WriteToOpenedFile
,
122 base::Unretained(this),
123 request_id
, data
, length
));
127 CallbackType
GetStatusType(int request_id
) {
128 if (status_map_
.find(request_id
) == status_map_
.end())
129 return CALLBACK_TYPE_ERROR
;
130 return status_map_
[request_id
].type
;
133 // Return the operation status.
134 CallbackStatus
& GetStatus(int request_id
) {
135 return status_map_
[request_id
];
138 int StatusQueueSize() {
139 return status_map_
.size();
142 int GetNextRequestId() {
143 return ++max_request_id_
;
146 void set_read_directory_buffer_size(int size
) {
147 file_util_
->set_read_directory_buffer_size(size
);
151 void StatusCallbackImpl(int request_id
, PlatformFileError result
) {
152 CallbackStatus status
;
153 status
.type
= CALLBACK_TYPE_STATUS
;
154 status
.result
= result
;
155 status_map_
[request_id
] = status
;
158 void GetFileInfoCallback(int request_id
,
159 PlatformFileError result
,
160 const base::PlatformFileInfo
& file_info
) {
161 CallbackStatus status
;
162 status
.type
= CALLBACK_TYPE_GET_FILE_INFO
;
163 status
.result
= result
;
164 status
.file_info
= file_info
;
165 status_map_
[request_id
] = status
;
168 void OpenCallback(int request_id
,
169 PlatformFileError result
,
170 AsyncFileStream
* file_stream
) {
171 DCHECK(status_map_
.find(request_id
) == status_map_
.end());
172 CallbackStatus status
;
173 status
.type
= CALLBACK_TYPE_OPEN
;
174 status
.result
= result
;
175 status
.file_stream
= file_stream
;
176 status_map_
[request_id
] = status
;
179 void ReadWriteCallbackImpl(int request_id
,
180 PlatformFileError result
,
182 CallbackStatus status
;
183 status
.type
= CALLBACK_TYPE_READ_WRITE
;
184 status
.result
= result
;
185 status
.length
= length
;
186 status_map_
[request_id
] = status
;
189 void ReadDirectoryCallback(int request_id
,
190 PlatformFileError result
,
191 const FileUtilAsync::FileList
& entries
,
193 if (status_map_
.find(request_id
) == status_map_
.end()) {
194 CallbackStatus status
;
195 status
.type
= CALLBACK_TYPE_READ_DIRECTORY
;
196 status
.called_after_completed
= false;
197 status
.result
= result
;
198 status
.completed
= completed
;
200 status
.entries
= entries
;
201 status_map_
[request_id
] = status
;
203 CallbackStatus
& status
= status_map_
[request_id
];
204 if (status
.completed
)
205 status
.called_after_completed
= true;
206 status
.result
= result
;
207 status
.completed
= completed
;
209 status
.entries
.insert(status
.entries
.begin(), entries
.begin(),
214 void WriteToOpenedFile(int request_id
,
217 PlatformFileError result
,
218 AsyncFileStream
* stream
) {
219 DCHECK(status_map_
.find(request_id
) == status_map_
.end());
220 CallbackStatus status
;
221 status
.type
= CALLBACK_TYPE_OPEN
;
222 status
.result
= result
;
223 status
.file_stream
= stream
;
224 status_map_
[request_id
] = status
;
225 stream
->Write(data
, length
, GetReadWriteCallback(GetNextRequestId()));
228 scoped_ptr
<MemoryFileUtil
> file_util_
;
229 std::map
<int, CallbackStatus
> status_map_
;
232 DISALLOW_COPY_AND_ASSIGN(MemoryFileUtilTest
);
235 TEST_F(MemoryFileUtilTest
, TestCreateGetFileInfo
) {
236 const int request_id1
= GetNextRequestId();
237 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test.txt"),
238 GetGetFileInfoCallback(request_id1
));
240 // In case the file system is truely asynchronous, RunAllPending is not
241 // enough to wait for answer. In that case the thread should be blocked
242 // until the callback is called (ex. use Run() instead here, and call
243 // Quit() from callback).
244 MessageLoop::current()->RunUntilIdle();
246 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id1
));
247 CallbackStatus status
= GetStatus(request_id1
);
248 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status
.result
);
250 base::Time start_create
= base::Time::Now();
252 const int request_id2
= GetNextRequestId();
253 file_util()->Create(base::FilePath("/mnt/memory/test.txt"),
254 GetStatusCallback(request_id2
));
255 MessageLoop::current()->RunUntilIdle();
256 ASSERT_EQ(CALLBACK_TYPE_STATUS
, GetStatusType(request_id2
));
257 status
= GetStatus(request_id2
);
258 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
260 const int request_id3
= GetNextRequestId();
261 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test.txt"),
262 GetGetFileInfoCallback(request_id3
));
263 MessageLoop::current()->RunUntilIdle();
265 base::Time end_create
= base::Time::Now();
267 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id3
));
268 status
= GetStatus(request_id3
);
269 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
270 ASSERT_EQ(0, status
.file_info
.size
);
271 ASSERT_FALSE(status
.file_info
.is_directory
);
272 ASSERT_FALSE(status
.file_info
.is_symbolic_link
);
273 ASSERT_GE(status
.file_info
.last_modified
, start_create
);
274 ASSERT_LE(status
.file_info
.last_modified
, end_create
);
275 ASSERT_GE(status
.file_info
.creation_time
, start_create
);
276 ASSERT_LE(status
.file_info
.creation_time
, end_create
);
279 TEST_F(MemoryFileUtilTest
, TestReadWrite
) {
280 // Check that the file does not exist.
282 const int request_id1
= GetNextRequestId();
283 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
284 GetGetFileInfoCallback(request_id1
));
286 MessageLoop::current()->RunUntilIdle();
288 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id1
));
289 CallbackStatus status
= GetStatus(request_id1
);
290 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status
.result
);
292 // Create & open file for writing.
294 base::Time start_create
= base::Time::Now();
295 const int request_id2
= GetNextRequestId();
296 file_util()->Open(base::FilePath("/mnt/memory/test1.txt"),
297 base::PLATFORM_FILE_CREATE_ALWAYS
|
298 base::PLATFORM_FILE_WRITE
,
299 GetOpenCallback(request_id2
));
300 MessageLoop::current()->RunUntilIdle();
302 base::Time end_create
= base::Time::Now();
304 ASSERT_EQ(CALLBACK_TYPE_OPEN
, GetStatusType(request_id2
));
305 status
= GetStatus(request_id2
);
306 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
308 AsyncFileStream
* write_file_stream
= status
.file_stream
;
310 // Check that file was created and has 0 size.
312 const int request_id3
= GetNextRequestId();
313 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
314 GetGetFileInfoCallback(request_id3
));
315 MessageLoop::current()->RunUntilIdle();
317 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id3
));
318 status
= GetStatus(request_id3
);
319 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
320 ASSERT_EQ(0, status
.file_info
.size
);
321 ASSERT_FALSE(status
.file_info
.is_directory
);
322 ASSERT_FALSE(status
.file_info
.is_symbolic_link
);
323 ASSERT_GE(status
.file_info
.last_modified
, start_create
);
324 ASSERT_LE(status
.file_info
.last_modified
, end_create
);
326 // Write 10 bytes to file.
328 const int request_id4
= GetNextRequestId();
329 base::Time start_write
= base::Time::Now();
330 write_file_stream
->Write(kTestString
, 10,
331 GetReadWriteCallback(request_id4
));
332 MessageLoop::current()->RunUntilIdle();
333 base::Time end_write
= base::Time::Now();
335 ASSERT_EQ(CALLBACK_TYPE_READ_WRITE
, GetStatusType(request_id4
));
336 status
= GetStatus(request_id4
);
337 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
338 ASSERT_EQ(10, status
.length
);
340 // Check that the file has now size 10 and correct modification time.
342 const int request_id5
= GetNextRequestId();
343 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
344 GetGetFileInfoCallback(request_id5
));
345 MessageLoop::current()->RunUntilIdle();
347 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id5
));
348 status
= GetStatus(request_id5
);
349 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
350 ASSERT_EQ(10, status
.file_info
.size
);
351 ASSERT_GE(status
.file_info
.last_modified
, start_write
);
352 ASSERT_LE(status
.file_info
.last_modified
, end_write
);
354 // Write the rest of the string to file.
356 const int request_id6
= GetNextRequestId();
357 start_write
= base::Time::Now();
358 write_file_stream
->Write(kTestString
+ 10,
359 kTestStringLength
- 10,
360 GetReadWriteCallback(request_id6
));
361 MessageLoop::current()->RunUntilIdle();
362 end_write
= base::Time::Now();
364 ASSERT_EQ(CALLBACK_TYPE_READ_WRITE
, GetStatusType(request_id6
));
365 status
= GetStatus(request_id6
);
366 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
367 ASSERT_EQ(static_cast<int64
>(kTestStringLength
) - 10, status
.length
);
369 // Check the file size & modification time.
371 const int request_id7
= GetNextRequestId();
372 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
373 GetGetFileInfoCallback(request_id7
));
374 MessageLoop::current()->RunUntilIdle();
376 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id7
));
377 status
= GetStatus(request_id7
);
378 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
379 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.file_info
.size
);
380 ASSERT_GE(status
.file_info
.last_modified
, start_write
);
381 ASSERT_LE(status
.file_info
.last_modified
, end_write
);
383 // Open file for reading.
385 const int request_id8
= GetNextRequestId();
386 file_util()->Open(base::FilePath("/mnt/memory/test1.txt"),
387 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_READ
,
388 GetOpenCallback(request_id8
));
389 MessageLoop::current()->RunUntilIdle();
391 ASSERT_EQ(CALLBACK_TYPE_OPEN
, GetStatusType(request_id8
));
392 status
= GetStatus(request_id8
);
393 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
394 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
396 AsyncFileStream
* read_file_stream
= status
.file_stream
;
398 // Read the whole file
400 const int request_id9
= GetNextRequestId();
401 read_file_stream
->Read(buffer
, 1023, GetReadWriteCallback(request_id9
));
402 MessageLoop::current()->RunUntilIdle();
404 ASSERT_EQ(CALLBACK_TYPE_READ_WRITE
, GetStatusType(request_id9
));
405 status
= GetStatus(request_id9
);
406 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
407 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.length
);
409 buffer
[status
.length
] = '\0';
410 std::string
result_string(buffer
);
411 ASSERT_EQ(kTestString
, result_string
);
413 // Check that size & modification time have not changed.
415 const int request_id10
= GetNextRequestId();
416 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
417 GetGetFileInfoCallback(request_id10
));
418 MessageLoop::current()->RunUntilIdle();
420 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id10
));
421 status
= GetStatus(request_id10
);
422 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
423 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.file_info
.size
);
424 ASSERT_GE(status
.file_info
.last_modified
, start_write
);
425 ASSERT_LE(status
.file_info
.last_modified
, end_write
);
427 // Open once more for writing.
429 const int request_id11
= GetNextRequestId();
430 file_util()->Open(base::FilePath("/mnt/memory/test1.txt"),
431 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
432 GetOpenCallback(request_id11
));
433 MessageLoop::current()->RunUntilIdle();
435 ASSERT_EQ(CALLBACK_TYPE_OPEN
, GetStatusType(request_id11
));
436 status
= GetStatus(request_id11
);
437 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
439 AsyncFileStream
* write_file_stream2
= status
.file_stream
;
441 // Check that the size has not changed.
443 const int request_id12
= GetNextRequestId();
444 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
445 GetGetFileInfoCallback(request_id12
));
446 MessageLoop::current()->RunUntilIdle();
448 ASSERT_EQ(CALLBACK_TYPE_GET_FILE_INFO
, GetStatusType(request_id12
));
449 status
= GetStatus(request_id12
);
450 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
451 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.file_info
.size
);
453 // Seek beyond the end of file. Should return error.
455 const int request_id13
= GetNextRequestId();
456 write_file_stream2
->Seek(1000, GetStatusCallback(request_id13
));
457 MessageLoop::current()->RunUntilIdle();
458 ASSERT_EQ(CALLBACK_TYPE_STATUS
, GetStatusType(request_id13
));
459 status
= GetStatus(request_id13
);
460 ASSERT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status
.result
);
462 // Try to write to read-only stream.
464 const int request_id14
= GetNextRequestId();
465 read_file_stream
->Write(kTestString
,
467 GetReadWriteCallback(request_id14
));
468 MessageLoop::current()->RunUntilIdle();
469 status
= GetStatus(request_id14
);
470 ASSERT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status
.result
);
472 // Write data overlapping with already written.
475 const int request_id15
= GetNextRequestId();
476 write_file_stream2
->Seek(10, GetStatusCallback(request_id15
));
477 MessageLoop::current()->RunUntilIdle();
478 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id15
).result
);
480 const int request_id16
= GetNextRequestId();
481 write_file_stream2
->Write(kTestString
,
483 GetReadWriteCallback(request_id16
));
484 MessageLoop::current()->RunUntilIdle();
485 status
= GetStatus(request_id16
);
486 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
487 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.length
);
491 const int request_id17
= GetNextRequestId();
492 file_util()->GetFileInfo(base::FilePath("/mnt/memory/test1.txt"),
493 GetGetFileInfoCallback(request_id17
));
494 MessageLoop::current()->RunUntilIdle();
495 status
= GetStatus(request_id17
);
496 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
497 ASSERT_EQ(static_cast<int64
>(kTestStringLength
) + 10,
498 status
.file_info
.size
);
500 // Read from 10th byte.
501 const int request_id18
= GetNextRequestId();
502 read_file_stream
->Seek(10, GetStatusCallback(request_id18
));
503 MessageLoop::current()->RunUntilIdle();
504 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id18
).result
);
506 const int request_id19
= GetNextRequestId();
507 read_file_stream
->Read(buffer
, 1023, GetReadWriteCallback(request_id19
));
508 MessageLoop::current()->RunUntilIdle();
509 status
= GetStatus(request_id19
);
510 ASSERT_EQ(base::PLATFORM_FILE_OK
, status
.result
);
511 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), status
.length
);
512 buffer
[status
.length
] = '\0';
513 std::string
result_string2(buffer
);
514 ASSERT_EQ(kTestString
, result_string2
);
517 // The directory structure we'll be testing on:
522 // /mnt/memory/b/c kTestStringLength
525 // /mnt/memory/b/f kTestStringLength
527 // /mnt/memory/b/g/h 0
528 // /mnt/memory/b/i kTestStringLength
530 // /mnt/memory/longer_file_name.txt kTestStringLength
531 TEST_F(MemoryFileUtilTest
, TestDirectoryOperations
) {
532 // Check the directory is empty.
533 const int request_id0
= GetNextRequestId();
534 file_util()->ReadDirectory(base::FilePath("/mnt/memory/"),
535 GetReadDirectoryCallback(request_id0
));
537 MessageLoop::current()->RunUntilIdle();
539 ASSERT_EQ(CALLBACK_TYPE_READ_DIRECTORY
, GetStatusType(request_id0
));
540 CallbackStatus
& status
= GetStatus(request_id0
);
541 ASSERT_TRUE(status
.completed
);
542 ASSERT_FALSE(status
.called_after_completed
);
543 ASSERT_EQ(1, status
.called
);
544 ASSERT_EQ(0u, status
.entries
.size());
546 // Create /mnt/memory/a, /mnt/memory/b/, /mnt/memory/longer_file_name.txt,
547 // /mnt/memory/c/ asyncronously (i.e. we do not wait for each operation to
548 // complete before starting the next one.
550 base::Time start_create
= base::Time::Now();
551 CreateEmptyFile(base::FilePath("/mnt/memory/a"));
553 int request_id1
= GetNextRequestId();
554 file_util()->CreateDirectory(base::FilePath("/mnt/memory/b"),
555 GetStatusCallback(request_id1
));
557 CreateNonEmptyFile(base::FilePath("/mnt/memory/longer_file_name.txt"),
561 int request_id2
= GetNextRequestId();
562 file_util()->CreateDirectory(base::FilePath("/mnt/memory/c"),
563 GetStatusCallback(request_id2
));
565 MessageLoop::current()->RunUntilIdle();
566 base::Time end_create
= base::Time::Now();
568 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
569 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id2
).result
);
571 // ReadDirectory /mnt/memory, /mnt/memory/a (not a dir), /mnt/memory/b/,
572 // /mnt/memory/d (not found)
574 set_read_directory_buffer_size(5); // Should complete in one go.
576 request_id1
= GetNextRequestId();
577 file_util()->ReadDirectory(base::FilePath("/mnt/memory"),
578 GetReadDirectoryCallback(request_id1
));
579 request_id2
= GetNextRequestId();
580 file_util()->ReadDirectory(base::FilePath("/mnt/memory/a"),
581 GetReadDirectoryCallback(request_id2
));
582 const int request_id3
= GetNextRequestId();
583 file_util()->ReadDirectory(base::FilePath("/mnt/memory/b/"),
584 GetReadDirectoryCallback(request_id3
));
585 const int request_id4
= GetNextRequestId();
586 file_util()->ReadDirectory(base::FilePath("/mnt/memory/d/"),
587 GetReadDirectoryCallback(request_id4
));
589 MessageLoop::current()->RunUntilIdle();
591 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
592 status
= GetStatus(request_id1
);
593 ASSERT_TRUE(status
.completed
);
594 ASSERT_FALSE(status
.called_after_completed
);
595 ASSERT_EQ(1, status
.called
); // Because the number of entries < 5.
596 ASSERT_EQ(4u, status
.entries
.size());
598 std::set
<base::FilePath::StringType
> seen
;
600 for (FileUtilAsync::FileList::const_iterator it
= status
.entries
.begin();
601 it
!= status
.entries
.end();
603 ASSERT_LE(start_create
, it
->last_modified_time
);
604 ASSERT_GE(end_create
, it
->last_modified_time
);
606 ASSERT_EQ(seen
.end(), seen
.find(it
->name
));
607 seen
.insert(it
->name
);
609 if (it
->name
== "a") {
610 ASSERT_FALSE(it
->is_directory
);
611 ASSERT_EQ(0, it
->size
);
612 } else if (it
->name
== "b") {
613 ASSERT_TRUE(it
->is_directory
);
614 } else if (it
->name
== "c") {
615 ASSERT_TRUE(it
->is_directory
);
616 } else if (it
->name
== "longer_file_name.txt") {
617 ASSERT_FALSE(it
->is_directory
);
618 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), it
->size
);
620 LOG(ERROR
) << "Unexpected file: " << it
->name
;
625 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
626 GetStatus(request_id2
).result
);
628 status
= GetStatus(request_id3
);
629 ASSERT_TRUE(status
.completed
);
630 ASSERT_FALSE(status
.called_after_completed
);
631 ASSERT_EQ(1, status
.called
);
632 ASSERT_EQ(0u, status
.entries
.size());
634 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, GetStatus(request_id4
).result
);
636 // Create files & dirs inside b/:
637 // /mnt/memory/b/c kTestStringLength
640 // /mnt/memory/b/f kTestStringLength
642 // /mnt/memory/b/i kTestStringLength
644 // /mnt/memory/b/g/h 0
646 start_create
= base::Time::Now();
647 CreateNonEmptyFile(base::FilePath("/mnt/memory/b/c"),
650 request_id1
= GetNextRequestId();
651 file_util()->CreateDirectory(base::FilePath("/mnt/memory/b/d"),
652 GetStatusCallback(request_id1
));
653 CreateEmptyFile(base::FilePath("/mnt/memory/b/e"));
654 CreateNonEmptyFile(base::FilePath("/mnt/memory/b/f"),
657 request_id2
= GetNextRequestId();
658 file_util()->CreateDirectory(base::FilePath("/mnt/memory/b/g"),
659 GetStatusCallback(request_id1
));
660 CreateNonEmptyFile(base::FilePath("/mnt/memory/b/i"),
664 MessageLoop::current()->RunUntilIdle();
666 CreateEmptyFile(base::FilePath("/mnt/memory/b/g/h"));
668 MessageLoop::current()->RunUntilIdle();
669 end_create
= base::Time::Now();
671 // Read /mnt/memory and check that the number of entries is unchanged.
673 request_id1
= GetNextRequestId();
674 file_util()->ReadDirectory(base::FilePath("/mnt/memory"),
675 GetReadDirectoryCallback(request_id1
));
677 MessageLoop::current()->RunUntilIdle();
679 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
680 status
= GetStatus(request_id1
);
681 ASSERT_TRUE(status
.completed
);
682 ASSERT_FALSE(status
.called_after_completed
);
683 ASSERT_EQ(1, status
.called
); // Because the number of entries < 5.
684 ASSERT_EQ(4u, status
.entries
.size());
686 // Read /mnt/memory/b
688 request_id1
= GetNextRequestId();
689 file_util()->ReadDirectory(base::FilePath("/mnt/memory/b"),
690 GetReadDirectoryCallback(request_id1
));
692 MessageLoop::current()->RunUntilIdle();
694 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
695 status
= GetStatus(request_id1
);
696 ASSERT_TRUE(status
.completed
);
697 ASSERT_FALSE(status
.called_after_completed
);
698 ASSERT_EQ(2, status
.called
); // Because the number of entries > 5.
699 ASSERT_EQ(6u, status
.entries
.size());
703 for (FileUtilAsync::FileList::const_iterator it
= status
.entries
.begin();
704 it
!= status
.entries
.end();
706 ASSERT_LE(start_create
, it
->last_modified_time
);
707 ASSERT_GE(end_create
, it
->last_modified_time
);
709 ASSERT_EQ(seen
.end(), seen
.find(it
->name
));
710 seen
.insert(it
->name
);
712 // /mnt/memory/b/c kTestStringLength
715 // /mnt/memory/b/f kTestStringLength
717 // /mnt/memory/b/i kTestStringLength
719 if (it
->name
== "c") {
720 ASSERT_FALSE(it
->is_directory
);
721 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), it
->size
);
722 } else if (it
->name
== "d") {
723 ASSERT_TRUE(it
->is_directory
);
724 } else if (it
->name
== "e") {
725 ASSERT_FALSE(it
->is_directory
);
726 ASSERT_EQ(0, it
->size
);
727 } else if (it
->name
== "f") {
728 ASSERT_FALSE(it
->is_directory
);
729 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), it
->size
);
730 } else if (it
->name
== "g") {
731 ASSERT_TRUE(it
->is_directory
);
732 } else if (it
->name
== "i") {
733 ASSERT_FALSE(it
->is_directory
);
734 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), it
->size
);
736 LOG(ERROR
) << "Unexpected file: " << it
->name
;
741 // Remove single file: /mnt/memory/b/f
743 request_id1
= GetNextRequestId();
744 file_util()->Remove(base::FilePath("/mnt/memory/b/f"), false /* recursive */,
745 GetStatusCallback(request_id1
));
746 MessageLoop::current()->RunUntilIdle();
747 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
749 // Check the number of files in b/
751 request_id1
= GetNextRequestId();
752 file_util()->ReadDirectory(base::FilePath("/mnt/memory/b"),
753 GetReadDirectoryCallback(request_id1
));
755 MessageLoop::current()->RunUntilIdle();
757 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
758 status
= GetStatus(request_id1
);
759 ASSERT_TRUE(status
.completed
);
760 ASSERT_FALSE(status
.called_after_completed
);
761 ASSERT_EQ(5u, status
.entries
.size());
763 // Try remove /mnt/memory/b non-recursively (error)
765 request_id1
= GetNextRequestId();
766 file_util()->Remove(base::FilePath("/mnt/memory/b"), false /* recursive */,
767 GetStatusCallback(request_id1
));
768 MessageLoop::current()->RunUntilIdle();
769 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE
,
770 GetStatus(request_id1
).result
);
772 // Non-recursively remove empty directory.
774 request_id1
= GetNextRequestId();
775 file_util()->Remove(base::FilePath("/mnt/memory/b/d"), false /* recursive */,
776 GetStatusCallback(request_id1
));
777 MessageLoop::current()->RunUntilIdle();
778 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
780 request_id1
= GetNextRequestId();
781 file_util()->GetFileInfo(base::FilePath("/mnt/memory/b/d"),
782 GetGetFileInfoCallback(request_id1
));
783 MessageLoop::current()->RunUntilIdle();
784 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, GetStatus(request_id1
).result
);
786 // Remove /mnt/memory/b recursively.
788 request_id1
= GetNextRequestId();
789 file_util()->Remove(base::FilePath("/mnt/memory/b"), true /* recursive */,
790 GetStatusCallback(request_id1
));
791 MessageLoop::current()->RunUntilIdle();
792 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
794 // ReadDirectory /mnt/memory/b -> not found
796 request_id1
= GetNextRequestId();
797 file_util()->ReadDirectory(base::FilePath("/mnt/memory/b"),
798 GetReadDirectoryCallback(request_id1
));
799 MessageLoop::current()->RunUntilIdle();
800 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, GetStatus(request_id1
).result
);
802 // ReadDirectory /mnt/memory
804 request_id1
= GetNextRequestId();
805 file_util()->ReadDirectory(base::FilePath("/mnt/memory"),
806 GetReadDirectoryCallback(request_id1
));
808 MessageLoop::current()->RunUntilIdle();
810 ASSERT_EQ(base::PLATFORM_FILE_OK
, GetStatus(request_id1
).result
);
811 status
= GetStatus(request_id1
);
812 ASSERT_TRUE(status
.completed
);
813 ASSERT_FALSE(status
.called_after_completed
);
814 ASSERT_EQ(3u, status
.entries
.size());
818 for (FileUtilAsync::FileList::const_iterator it
= status
.entries
.begin();
819 it
!= status
.entries
.end();
821 ASSERT_EQ(seen
.end(), seen
.find(it
->name
));
822 seen
.insert(it
->name
);
824 if (it
->name
== "a") {
825 ASSERT_FALSE(it
->is_directory
);
826 ASSERT_EQ(0, it
->size
);
827 } else if (it
->name
== "c") {
828 ASSERT_TRUE(it
->is_directory
);
829 } else if (it
->name
== "longer_file_name.txt") {
830 ASSERT_FALSE(it
->is_directory
);
831 ASSERT_EQ(static_cast<int64
>(kTestStringLength
), it
->size
);
833 LOG(ERROR
) << "Unexpected file: " << it
->name
;
839 } // namespace fileapi