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.
5 #include "ppapi/tests/test_file_ref.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppb_file_io.h"
12 #include "ppapi/c/dev/ppb_testing_dev.h"
13 #include "ppapi/cpp/file_io.h"
14 #include "ppapi/cpp/file_ref.h"
15 #include "ppapi/cpp/file_system.h"
16 #include "ppapi/cpp/instance.h"
17 #include "ppapi/cpp/module.h"
18 #include "ppapi/cpp/url_loader.h"
19 #include "ppapi/cpp/url_request_info.h"
20 #include "ppapi/cpp/url_response_info.h"
21 #include "ppapi/tests/test_utils.h"
22 #include "ppapi/tests/testing_instance.h"
24 REGISTER_TEST_CASE(FileRef
);
28 const char* kPersFileName
= "persistent";
29 const char* kTempFileName
= "temporary";
30 const char* kParentPath
= "/foo/bar";
31 const char* kPersFilePath
= "/foo/bar/persistent";
32 const char* kTempFilePath
= "/foo/bar/temporary";
34 std::string
ReportMismatch(const std::string
& method_name
,
35 const std::string
& returned_result
,
36 const std::string
& expected_result
) {
37 return method_name
+ " returned '" + returned_result
+ "'; '" +
38 expected_result
+ "' expected.";
43 bool TestFileRef::Init() {
44 return InitTestingInterface() && EnsureRunningOverHTTP();
47 void TestFileRef::RunTest() {
48 RUN_TEST_FORCEASYNC_AND_NOT(Create
);
49 RUN_TEST_FORCEASYNC_AND_NOT(GetFileSystemType
);
50 RUN_TEST_FORCEASYNC_AND_NOT(GetName
);
51 RUN_TEST_FORCEASYNC_AND_NOT(GetPath
);
52 RUN_TEST_FORCEASYNC_AND_NOT(GetParent
);
53 RUN_TEST_FORCEASYNC_AND_NOT(MakeDirectory
);
54 RUN_TEST_FORCEASYNC_AND_NOT(QueryAndTouchFile
);
55 RUN_TEST_FORCEASYNC_AND_NOT(DeleteFileAndDirectory
);
56 RUN_TEST_FORCEASYNC_AND_NOT(RenameFileAndDirectory
);
59 std::string
TestFileRef::TestCreate() {
60 std::vector
<std::string
> invalid_paths
;
61 invalid_paths
.push_back("invalid_path"); // no '/' at the first character
62 invalid_paths
.push_back(""); // empty path
63 // The following are directory traversal checks
64 invalid_paths
.push_back("..");
65 invalid_paths
.push_back("/../invalid_path");
66 invalid_paths
.push_back("/../../invalid_path");
67 invalid_paths
.push_back("/invalid/../../path");
68 const size_t num_invalid_paths
= invalid_paths
.size();
70 pp::FileSystem
file_system_pers(
71 instance_
, PP_FILESYSTEMTYPE_LOCALPERSISTENT
);
72 pp::FileSystem
file_system_temp(
73 instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
74 for (size_t j
= 0; j
< num_invalid_paths
; ++j
) {
75 pp::FileRef
file_ref_pers(file_system_pers
, invalid_paths
[j
].c_str());
76 if (file_ref_pers
.pp_resource() != 0) {
77 return "file_ref_pers expected to be invalid for path: " +
80 pp::FileRef
file_ref_temp(file_system_temp
, invalid_paths
[j
].c_str());
81 if (file_ref_temp
.pp_resource() != 0) {
82 return "file_ref_temp expected to be invalid for path: " +
89 std::string
TestFileRef::TestGetFileSystemType() {
90 pp::FileSystem
file_system_pers(
91 instance_
, PP_FILESYSTEMTYPE_LOCALPERSISTENT
);
92 pp::FileSystem
file_system_temp(
93 instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
95 pp::FileRef
file_ref_pers(file_system_pers
, kPersFilePath
);
96 if (file_ref_pers
.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT
)
97 return "file_ref_pers expected to be persistent.";
99 pp::FileRef
file_ref_temp(file_system_temp
, kTempFilePath
);
100 if (file_ref_temp
.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY
)
101 return "file_ref_temp expected to be temporary.";
103 pp::URLRequestInfo
request(instance_
);
104 request
.SetURL("test_url_loader_data/hello.txt");
105 request
.SetStreamToFile(true);
107 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
109 pp::URLLoader
loader(instance_
);
110 int32_t rv
= loader
.Open(request
, callback
);
111 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
112 return ReportError("URLLoader::Open force_async", rv
);
113 if (rv
== PP_OK_COMPLETIONPENDING
)
114 rv
= callback
.WaitForResult();
116 return "URLLoader::Open() failed.";
118 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
119 if (response_info
.is_null())
120 return "URLLoader::GetResponseInfo returned null";
121 int32_t status_code
= response_info
.GetStatusCode();
122 if (status_code
!= 200)
123 return "Unexpected HTTP status code";
125 pp::FileRef
file_ref_ext(response_info
.GetBodyAsFileRef());
126 if (file_ref_ext
.GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL
)
127 return "file_ref_ext expected to be external.";
132 std::string
TestFileRef::TestGetName() {
133 pp::FileSystem
file_system_pers(
134 instance_
, PP_FILESYSTEMTYPE_LOCALPERSISTENT
);
135 pp::FileSystem
file_system_temp(
136 instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
138 pp::FileRef
file_ref_pers(file_system_pers
, kPersFilePath
);
139 std::string name
= file_ref_pers
.GetName().AsString();
140 if (name
!= kPersFileName
)
141 return ReportMismatch("FileRef::GetName", name
, kPersFileName
);
143 pp::FileRef
file_ref_temp(file_system_temp
, kTempFilePath
);
144 name
= file_ref_temp
.GetName().AsString();
145 if (name
!= kTempFileName
)
146 return ReportMismatch("FileRef::GetName", name
, kTempFileName
);
148 // Test the "/" case.
149 pp::FileRef
file_ref_slash(file_system_temp
, "/");
150 name
= file_ref_slash
.GetName().AsString();
152 return ReportMismatch("FileRef::GetName", name
, "/");
154 pp::URLRequestInfo
request(instance_
);
155 request
.SetURL("test_url_loader_data/hello.txt");
156 request
.SetStreamToFile(true);
158 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
160 pp::URLLoader
loader(instance_
);
161 int32_t rv
= loader
.Open(request
, callback
);
162 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
163 return ReportError("URLLoader::Open force_async", rv
);
164 if (rv
== PP_OK_COMPLETIONPENDING
)
165 rv
= callback
.WaitForResult();
167 return "URLLoader::Open() failed.";
169 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
170 if (response_info
.is_null())
171 return "URLLoader::GetResponseInfo returned null";
172 int32_t status_code
= response_info
.GetStatusCode();
173 if (status_code
!= 200)
174 return "Unexpected HTTP status code";
176 pp::FileRef
file_ref_ext(response_info
.GetBodyAsFileRef());
177 name
= file_ref_ext
.GetName().AsString();
179 return ReportMismatch("FileRef::GetName", name
, "<a temp file>");
184 std::string
TestFileRef::TestGetPath() {
185 pp::FileSystem
file_system_pers(
186 instance_
, PP_FILESYSTEMTYPE_LOCALPERSISTENT
);
187 pp::FileSystem
file_system_temp(
188 instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
190 pp::FileRef
file_ref_pers(file_system_pers
, kPersFilePath
);
191 std::string path
= file_ref_pers
.GetPath().AsString();
192 if (path
!= kPersFilePath
)
193 return ReportMismatch("FileRef::GetPath", path
, kPersFilePath
);
195 pp::FileRef
file_ref_temp(file_system_temp
, kTempFilePath
);
196 path
= file_ref_temp
.GetPath().AsString();
197 if (path
!= kTempFilePath
)
198 return ReportMismatch("FileRef::GetPath", path
, kTempFilePath
);
200 pp::URLRequestInfo
request(instance_
);
201 request
.SetURL("test_url_loader_data/hello.txt");
202 request
.SetStreamToFile(true);
204 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
206 pp::URLLoader
loader(instance_
);
207 int32_t rv
= loader
.Open(request
, callback
);
208 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
209 return ReportError("URLLoader::Open force_async", rv
);
210 if (rv
== PP_OK_COMPLETIONPENDING
)
211 rv
= callback
.WaitForResult();
213 return "URLLoader::Open() failed.";
215 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
216 if (response_info
.is_null())
217 return "URLLoader::GetResponseInfo returned null";
218 int32_t status_code
= response_info
.GetStatusCode();
219 if (status_code
!= 200)
220 return "Unexpected HTTP status code";
222 pp::FileRef
file_ref_ext(response_info
.GetBodyAsFileRef());
223 if (!file_ref_ext
.GetPath().is_undefined())
224 return "The path of an external FileRef should be void.";
229 std::string
TestFileRef::TestGetParent() {
230 pp::FileSystem
file_system_pers(
231 instance_
, PP_FILESYSTEMTYPE_LOCALPERSISTENT
);
232 pp::FileSystem
file_system_temp(
233 instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
235 pp::FileRef
file_ref_pers(file_system_pers
, kPersFilePath
);
236 std::string parent_path
= file_ref_pers
.GetParent().GetPath().AsString();
237 if (parent_path
!= kParentPath
)
238 return ReportMismatch("FileRef::GetParent", parent_path
, kParentPath
);
240 pp::FileRef
file_ref_temp(file_system_temp
, kTempFilePath
);
241 parent_path
= file_ref_temp
.GetParent().GetPath().AsString();
242 if (parent_path
!= kParentPath
)
243 return ReportMismatch("FileRef::GetParent", parent_path
, kParentPath
);
245 // Test the "/" case.
246 pp::FileRef
file_ref_slash(file_system_temp
, "/");
247 parent_path
= file_ref_slash
.GetParent().GetPath().AsString();
248 if (parent_path
!= "/")
249 return ReportMismatch("FileRef::GetParent", parent_path
, "/");
251 // Test the "/foo" case (the parent is "/").
252 pp::FileRef
file_ref_with_root_parent(file_system_temp
, "/foo");
253 parent_path
= file_ref_with_root_parent
.GetParent().GetPath().AsString();
254 if (parent_path
!= "/")
255 return ReportMismatch("FileRef::GetParent", parent_path
, "/");
257 pp::URLRequestInfo
request(instance_
);
258 request
.SetURL("test_url_loader_data/hello.txt");
259 request
.SetStreamToFile(true);
261 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
263 pp::URLLoader
loader(instance_
);
264 int32_t rv
= loader
.Open(request
, callback
);
265 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
266 return ReportError("URLLoader::Open force_async", rv
);
267 if (rv
== PP_OK_COMPLETIONPENDING
)
268 rv
= callback
.WaitForResult();
270 return "URLLoader::Open() failed.";
272 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
273 if (response_info
.is_null())
274 return "URLLoader::GetResponseInfo returned null";
275 int32_t status_code
= response_info
.GetStatusCode();
276 if (status_code
!= 200)
277 return "Unexpected HTTP status code";
279 pp::FileRef
file_ref_ext(response_info
.GetBodyAsFileRef());
280 if (!file_ref_ext
.GetParent().is_null())
281 return "The parent of an external FileRef should be null.";
286 std::string
TestFileRef::TestMakeDirectory() {
287 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
290 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
291 int32_t rv
= file_system
.Open(1024, callback
);
292 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
293 return ReportError("FileSystem::Open force_async", rv
);
294 if (rv
== PP_OK_COMPLETIONPENDING
)
295 rv
= callback
.WaitForResult();
297 return ReportError("FileSystem::Open", rv
);
300 pp::FileRef
dir_ref(file_system
, "/test_dir_make_directory");
301 rv
= dir_ref
.MakeDirectory(callback
);
302 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
303 return ReportError("FileSystem::MakeDirectory force_async", rv
);
304 if (rv
== PP_OK_COMPLETIONPENDING
)
305 rv
= callback
.WaitForResult();
307 return ReportError("FileSystem::MakeDirectory", rv
);
309 // MakeDirectory aborted.
310 callback
.reset_run_count();
311 rv
= pp::FileRef(file_system
, "/test_dir_make_abort")
312 .MakeDirectory(callback
);
313 if (callback
.run_count() > 0)
314 return "FileSystem::MakeDirectory ran callback synchronously.";
315 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
316 return ReportError("FileSystem::MakeDirectory force_async", rv
);
317 if (rv
== PP_OK_COMPLETIONPENDING
) {
318 rv
= callback
.WaitForResult();
319 if (rv
!= PP_ERROR_ABORTED
)
320 return "FileSystem::MakeDirectory not aborted.";
321 } else if (rv
!= PP_OK
) {
322 return ReportError("FileSystem::MakeDirectory", rv
);
325 // MakeDirectoryIncludingAncestors.
326 dir_ref
= pp::FileRef(file_system
, "/dir_make_dir_1/dir_make_dir_2");
327 rv
= dir_ref
.MakeDirectoryIncludingAncestors(callback
);
328 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
329 return ReportError("FileSystem::MakeDirectory force_async", rv
);
330 if (rv
== PP_OK_COMPLETIONPENDING
)
331 rv
= callback
.WaitForResult();
333 return ReportError("FileSystem::MakeDirectoryIncludingAncestors", rv
);
335 // MakeDirectoryIncludingAncestors aborted.
336 callback
.reset_run_count();
337 rv
= pp::FileRef(file_system
, "/dir_make_abort_1/dir_make_abort_2")
338 .MakeDirectoryIncludingAncestors(callback
);
339 if (callback
.run_count() > 0) {
340 return "FileSystem::MakeDirectoryIncludingAncestors "
341 "ran callback synchronously.";
343 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
345 "FileSystem::MakeDirectoryIncludingAncestors force_async", rv
);
346 if (rv
== PP_OK_COMPLETIONPENDING
) {
347 rv
= callback
.WaitForResult();
348 if (rv
!= PP_ERROR_ABORTED
)
349 return "FileSystem::MakeDirectoryIncludingAncestors not aborted.";
350 } else if (rv
!= PP_OK
) {
351 return ReportError("FileSystem::MakeDirectoryIncludingAncestors", rv
);
354 // MakeDirectory with nested path.
355 dir_ref
= pp::FileRef(file_system
, "/dir_make_dir_3/dir_make_dir_4");
356 rv
= dir_ref
.MakeDirectory(callback
);
357 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
358 return ReportError("FileSystem::MakeDirectory force_async", rv
);
359 if (rv
== PP_OK_COMPLETIONPENDING
)
360 rv
= callback
.WaitForResult();
362 return "Calling FileSystem::MakeDirectory() with a nested directory path "
363 "should have failed.";
369 std::string
TestFileRef::TestQueryAndTouchFile() {
370 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
371 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
372 int32_t rv
= file_system
.Open(1024, callback
);
373 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
374 return ReportError("FileSystem::Open force_async", rv
);
375 if (rv
== PP_OK_COMPLETIONPENDING
)
376 rv
= callback
.WaitForResult();
378 return ReportError("FileSystem::Open", rv
);
380 pp::FileRef
file_ref(file_system
, "/file_touch");
381 pp::FileIO
file_io(instance_
);
382 rv
= file_io
.Open(file_ref
,
383 PP_FILEOPENFLAG_CREATE
|
384 PP_FILEOPENFLAG_TRUNCATE
|
385 PP_FILEOPENFLAG_WRITE
,
387 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
388 return ReportError("FileIO::Open force_async", rv
);
389 if (rv
== PP_OK_COMPLETIONPENDING
)
390 rv
= callback
.WaitForResult();
392 return ReportError("FileIO::Open", rv
);
394 // Write some data to have a non-zero file size.
395 rv
= file_io
.Write(0, "test", 4, callback
);
396 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
397 return ReportError("FileIO::Write force_async", rv
);
398 if (rv
== PP_OK_COMPLETIONPENDING
)
399 rv
= callback
.WaitForResult();
401 return ReportError("FileIO::Write", rv
);
404 // last_access_time's granularity is 1 day
405 // last_modified_time's granularity is 2 seconds
406 const PP_Time last_access_time
= 123 * 24 * 3600.0;
407 const PP_Time last_modified_time
= 246.0;
408 rv
= file_ref
.Touch(last_access_time
, last_modified_time
, callback
);
409 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
410 return ReportError("FileSystem::Touch force_async", rv
);
411 if (rv
== PP_OK_COMPLETIONPENDING
)
412 rv
= callback
.WaitForResult();
414 return ReportError("FileSystem::Touch", rv
);
417 callback
.reset_run_count();
418 rv
= pp::FileRef(file_system
, "/file_touch_abort")
419 .Touch(last_access_time
, last_modified_time
, callback
);
420 if (callback
.run_count() > 0)
421 return "FileSystem::Touch ran callback synchronously.";
422 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
423 return ReportError("FileSystem::Touch force_async", rv
);
424 if (rv
== PP_OK_COMPLETIONPENDING
) {
425 rv
= callback
.WaitForResult();
426 if (rv
!= PP_ERROR_ABORTED
)
427 return "FileSystem::Touch not aborted.";
428 } else if (rv
!= PP_OK
) {
429 return ReportError("FileSystem::Touch", rv
);
434 rv
= file_io
.Query(&info
, callback
);
435 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
436 return ReportError("FileSystem::Query force_async", rv
);
437 if (rv
== PP_OK_COMPLETIONPENDING
)
438 rv
= callback
.WaitForResult();
440 return ReportError("FileSystem::Query", rv
);
442 if ((info
.size
!= 4) ||
443 (info
.type
!= PP_FILETYPE_REGULAR
) ||
444 (info
.system_type
!= PP_FILESYSTEMTYPE_LOCALTEMPORARY
) ||
445 (info
.last_access_time
!= last_access_time
) ||
446 (info
.last_modified_time
!= last_modified_time
))
447 return "FileSystem::Query() has returned bad data.";
449 // Cancellation test.
450 // TODO(viettrungluu): this test causes a bunch of LOG(WARNING)s; investigate.
451 callback
.reset_run_count();
452 // TODO(viettrungluu): check |info| for late writes.
453 rv
= pp::FileRef(file_system
, "/file_touch").Touch(
454 last_access_time
, last_modified_time
, callback
);
455 if (callback
.run_count() > 0)
456 return "FileSystem::Touch ran callback synchronously.";
457 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
458 return ReportError("FileSystem::Touch force_async", rv
);
459 if (rv
== PP_OK_COMPLETIONPENDING
) {
460 rv
= callback
.WaitForResult();
461 if (rv
!= PP_ERROR_ABORTED
)
462 return "FileSystem::Touch not aborted.";
463 } else if (rv
!= PP_OK
) {
464 return ReportError("FileSystem::Touch", rv
);
470 std::string
TestFileRef::TestDeleteFileAndDirectory() {
471 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
472 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
473 int32_t rv
= file_system
.Open(1024, callback
);
474 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
475 return ReportError("FileSystem::Open force_async", rv
);
476 if (rv
== PP_OK_COMPLETIONPENDING
)
477 rv
= callback
.WaitForResult();
479 return ReportError("FileSystem::Open", rv
);
481 pp::FileRef
file_ref(file_system
, "/file_delete");
482 pp::FileIO
file_io(instance_
);
483 rv
= file_io
.Open(file_ref
, PP_FILEOPENFLAG_CREATE
, callback
);
484 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
485 return ReportError("FileIO::Open force_async", rv
);
486 if (rv
== PP_OK_COMPLETIONPENDING
)
487 rv
= callback
.WaitForResult();
489 return ReportError("FileIO::Open", rv
);
491 rv
= file_ref
.Delete(callback
);
492 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
493 return ReportError("FileRef::Delete force_async", rv
);
494 if (rv
== PP_OK_COMPLETIONPENDING
)
495 rv
= callback
.WaitForResult();
497 return ReportError("FileRef::Delete", rv
);
499 pp::FileRef
dir_ref(file_system
, "/dir_delete");
500 rv
= dir_ref
.MakeDirectory(callback
);
501 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
502 return ReportError("FileRef::MakeDirectory force_async", rv
);
503 if (rv
== PP_OK_COMPLETIONPENDING
)
504 rv
= callback
.WaitForResult();
506 return ReportError("FileRef::MakeDirectory", rv
);
508 rv
= dir_ref
.Delete(callback
);
509 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
510 return ReportError("FileRef::Open force_async", rv
);
511 if (rv
== PP_OK_COMPLETIONPENDING
)
512 rv
= callback
.WaitForResult();
514 return ReportError("FileRef::Delete", rv
);
516 pp::FileRef
nested_dir_ref(file_system
, "/dir_delete_1/dir_delete_2");
517 rv
= nested_dir_ref
.MakeDirectoryIncludingAncestors(callback
);
518 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
519 return ReportError("FileRef::Open force_async", rv
);
520 if (rv
== PP_OK_COMPLETIONPENDING
)
521 rv
= callback
.WaitForResult();
523 return ReportError("FileRef::MakeDirectoryIncludingAncestors", rv
);
525 // Hang on to a ref to the parent; otherwise the callback will be aborted.
526 pp::FileRef parent_dir_ref
= nested_dir_ref
.GetParent();
527 rv
= parent_dir_ref
.Delete(callback
);
528 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
529 return ReportError("FileRef::Open force_async", rv
);
530 if (rv
== PP_OK_COMPLETIONPENDING
)
531 rv
= callback
.WaitForResult();
532 if (rv
!= PP_ERROR_FAILED
)
533 return ReportError("FileRef::Delete", rv
);
535 pp::FileRef
nonexistent_file_ref(file_system
, "/nonexistent_file_delete");
536 rv
= nonexistent_file_ref
.Delete(callback
);
537 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
538 return ReportError("FileRef::Open force_async", rv
);
539 if (rv
== PP_OK_COMPLETIONPENDING
)
540 rv
= callback
.WaitForResult();
541 if (rv
!= PP_ERROR_FILENOTFOUND
)
542 return ReportError("FileRef::Delete", rv
);
546 pp::FileRef
file_ref_abort(file_system
, "/file_delete_abort");
547 pp::FileIO
file_io_abort(instance_
);
548 rv
= file_io_abort
.Open(file_ref_abort
, PP_FILEOPENFLAG_CREATE
, callback
);
549 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
550 return ReportError("FileIO::Open force_async", rv
);
551 if (rv
== PP_OK_COMPLETIONPENDING
)
552 rv
= callback
.WaitForResult();
554 return ReportError("FileIO::Open", rv
);
556 callback
.reset_run_count();
557 rv
= file_ref_abort
.Delete(callback
);
559 if (callback
.run_count() > 0)
560 return "FileRef::Delete ran callback synchronously.";
561 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
562 return ReportError("FileRef::Open force_async", rv
);
563 if (rv
== PP_OK_COMPLETIONPENDING
) {
564 rv
= callback
.WaitForResult();
565 if (rv
!= PP_ERROR_ABORTED
)
566 return "FileRef::Delete not aborted.";
567 } else if (rv
!= PP_OK
) {
568 return ReportError("FileRef::Delete", rv
);
574 std::string
TestFileRef::TestRenameFileAndDirectory() {
575 TestCompletionCallback
callback(instance_
->pp_instance(), force_async_
);
576 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
577 int32_t rv
= file_system
.Open(1024, callback
);
578 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
579 return ReportError("FileSystem::Open force_async", rv
);
580 if (rv
== PP_OK_COMPLETIONPENDING
)
581 rv
= callback
.WaitForResult();
583 return ReportError("FileSystem::Open", rv
);
585 pp::FileRef
file_ref(file_system
, "/file_rename");
586 pp::FileIO
file_io(instance_
);
587 rv
= file_io
.Open(file_ref
, PP_FILEOPENFLAG_CREATE
, callback
);
588 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
589 return ReportError("FileIO::Open force_async", rv
);
590 if (rv
== PP_OK_COMPLETIONPENDING
)
591 rv
= callback
.WaitForResult();
593 return ReportError("FileIO::Open", rv
);
595 pp::FileRef
target_file_ref(file_system
, "/target_file_rename");
596 rv
= file_ref
.Rename(target_file_ref
, callback
);
597 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
598 return ReportError("FileRef::Rename force_async", rv
);
599 if (rv
== PP_OK_COMPLETIONPENDING
)
600 rv
= callback
.WaitForResult();
602 return ReportError("FileRef::Rename", rv
);
604 pp::FileRef
dir_ref(file_system
, "/dir_rename");
605 rv
= dir_ref
.MakeDirectory(callback
);
606 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
607 return ReportError("FileRef::MakeDirectory force_async", rv
);
608 if (rv
== PP_OK_COMPLETIONPENDING
)
609 rv
= callback
.WaitForResult();
611 return ReportError("FileRef::MakeDirectory", rv
);
613 pp::FileRef
target_dir_ref(file_system
, "/target_dir_rename");
614 rv
= dir_ref
.Rename(target_dir_ref
, callback
);
615 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
616 return ReportError("FileRef::Rename force_async", rv
);
617 if (rv
== PP_OK_COMPLETIONPENDING
)
618 rv
= callback
.WaitForResult();
620 return ReportError("FileRef::Rename", rv
);
622 pp::FileRef
nested_dir_ref(file_system
, "/dir_rename_1/dir_rename_2");
623 rv
= nested_dir_ref
.MakeDirectoryIncludingAncestors(callback
);
624 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
625 return ReportError("FileRef::MakeDirectory force_async", rv
);
626 if (rv
== PP_OK_COMPLETIONPENDING
)
627 rv
= callback
.WaitForResult();
629 return ReportError("FileRef::MakeDirectoryIncludingAncestors", rv
);
631 pp::FileRef
target_nested_dir_ref(file_system
, "/dir_rename_1");
632 rv
= nested_dir_ref
.Rename(target_nested_dir_ref
, callback
);
633 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
634 return ReportError("FileRef::Open force_async", rv
);
635 if (rv
== PP_OK_COMPLETIONPENDING
)
636 rv
= callback
.WaitForResult();
637 if (rv
!= PP_ERROR_FAILED
)
638 return ReportError("FileRef::Rename", rv
);
641 // TODO(viettrungluu): Figure out what we want to do if the target file
642 // resource is destroyed before completion.
643 pp::FileRef
target_file_ref_abort(file_system
,
644 "/target_file_rename_abort");
646 pp::FileRef
file_ref_abort(file_system
, "/file_rename_abort");
647 pp::FileIO
file_io_abort(instance_
);
648 rv
= file_io_abort
.Open(file_ref_abort
, PP_FILEOPENFLAG_CREATE
, callback
);
649 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
650 return ReportError("FileIO::Open force_async", rv
);
651 if (rv
== PP_OK_COMPLETIONPENDING
)
652 rv
= callback
.WaitForResult();
654 return ReportError("FileIO::Open", rv
);
656 callback
.reset_run_count();
657 rv
= file_ref_abort
.Rename(target_file_ref_abort
, callback
);
659 if (callback
.run_count() > 0)
660 return "FileSystem::Rename ran callback synchronously.";
661 if (force_async_
&& rv
!= PP_OK_COMPLETIONPENDING
)
662 return ReportError("FileSystem::Rename force_async", rv
);
663 if (rv
== PP_OK_COMPLETIONPENDING
) {
664 rv
= callback
.WaitForResult();
665 if (rv
!= PP_ERROR_ABORTED
)
666 return "FileSystem::Rename not aborted.";
667 } else if (rv
!= PP_OK
) {
668 return ReportError("FileSystem::Rename", rv
);