123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737 |
- // Copyright (c) 2011 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ppapi/tests/test_file_ref.h"
- #include <stddef.h>
- #include <stdio.h>
- #include <sstream>
- #include <vector>
- #include "ppapi/c/pp_errors.h"
- #include "ppapi/c/ppb_file_io.h"
- #include "ppapi/c/private/ppb_testing_private.h"
- #include "ppapi/cpp/dev/file_chooser_dev.h"
- #include "ppapi/cpp/directory_entry.h"
- #include "ppapi/cpp/file_io.h"
- #include "ppapi/cpp/file_ref.h"
- #include "ppapi/cpp/file_system.h"
- #include "ppapi/cpp/instance.h"
- #include "ppapi/cpp/module.h"
- #include "ppapi/cpp/url_loader.h"
- #include "ppapi/cpp/url_request_info.h"
- #include "ppapi/cpp/url_response_info.h"
- #include "ppapi/tests/test_utils.h"
- #include "ppapi/tests/testing_instance.h"
- REGISTER_TEST_CASE(FileRef);
- namespace {
- const char* kPersFileName = "persistent";
- const char* kTempFileName = "temporary";
- const char* kParentPath = "/foo/bar";
- const char* kPersFilePath = "/foo/bar/persistent";
- const char* kTempFilePath = "/foo/bar/temporary";
- const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?";
- typedef std::vector<pp::DirectoryEntry> DirEntries;
- std::string ReportMismatch(const std::string& method_name,
- const std::string& returned_result,
- const std::string& expected_result) {
- return method_name + " returned '" + returned_result + "'; '" +
- expected_result + "' expected.";
- }
- } // namespace
- bool TestFileRef::Init() {
- return CheckTestingInterface() && EnsureRunningOverHTTP();
- }
- std::string TestFileRef::MakeExternalFileRef(pp::FileRef* file_ref_ext) {
- pp::FileChooser_Dev file_chooser(instance(), PP_FILECHOOSERMODE_OPEN, "*");
- ASSERT_FALSE(file_chooser.is_null());
- TestCompletionCallbackWithOutput<std::vector<pp::FileRef> >
- filechooser_callback(instance_->pp_instance(), callback_type());
- filechooser_callback.WaitForResult(
- file_chooser.Show(filechooser_callback.GetCallback()));
- const std::vector<pp::FileRef>& output_ref = filechooser_callback.output();
- ASSERT_EQ(1u, output_ref.size());
- *file_ref_ext = output_ref[0];
- ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType());
- PASS();
- }
- int32_t TestFileRef::DeleteDirectoryRecursively(pp::FileRef* dir) {
- if (!dir)
- return PP_ERROR_BADARGUMENT;
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- TestCompletionCallbackWithOutput<DirEntries> output_callback(
- instance_->pp_instance(), callback_type());
- output_callback.WaitForResult(
- dir->ReadDirectoryEntries(output_callback.GetCallback()));
- int32_t rv = output_callback.result();
- if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
- return rv;
- DirEntries entries = output_callback.output();
- for (DirEntries::const_iterator it = entries.begin();
- it != entries.end();
- ++it) {
- pp::FileRef file_ref = it->file_ref();
- if (it->file_type() == PP_FILETYPE_DIRECTORY) {
- rv = DeleteDirectoryRecursively(&file_ref);
- if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
- return rv;
- } else {
- callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
- rv = callback.result();
- if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
- return rv;
- }
- }
- callback.WaitForResult(dir->Delete(callback.GetCallback()));
- return callback.result();
- }
- void TestFileRef::RunTests(const std::string& filter) {
- RUN_CALLBACK_TEST(TestFileRef, Create, filter);
- RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter);
- RUN_CALLBACK_TEST(TestFileRef, GetName, filter);
- RUN_CALLBACK_TEST(TestFileRef, GetPath, filter);
- RUN_CALLBACK_TEST(TestFileRef, GetParent, filter);
- RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter);
- RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter);
- RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter);
- RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter);
- RUN_CALLBACK_TEST(TestFileRef, Query, filter);
- RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter);
- RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter);
- }
- std::string TestFileRef::TestCreate() {
- std::vector<std::string> invalid_paths;
- invalid_paths.push_back("invalid_path"); // no '/' at the first character
- invalid_paths.push_back(std::string()); // empty path
- // The following are directory traversal checks
- invalid_paths.push_back("..");
- invalid_paths.push_back("/../invalid_path");
- invalid_paths.push_back("/../../invalid_path");
- invalid_paths.push_back("/invalid/../../path");
- const size_t num_invalid_paths = invalid_paths.size();
- pp::FileSystem file_system_pers(
- instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- pp::FileSystem file_system_temp(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- for (size_t j = 0; j < num_invalid_paths; ++j) {
- pp::FileRef file_ref_pers(file_system_pers, invalid_paths[j].c_str());
- if (file_ref_pers.pp_resource() != 0) {
- return "file_ref_pers expected to be invalid for path: " +
- invalid_paths[j];
- }
- pp::FileRef file_ref_temp(file_system_temp, invalid_paths[j].c_str());
- if (file_ref_temp.pp_resource() != 0) {
- return "file_ref_temp expected to be invalid for path: " +
- invalid_paths[j];
- }
- }
- PASS();
- }
- std::string TestFileRef::TestGetFileSystemType() {
- pp::FileSystem file_system_pers(
- instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- pp::FileSystem file_system_temp(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
- if (file_ref_pers.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT)
- return "file_ref_pers expected to be persistent.";
- pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
- if (file_ref_temp.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)
- return "file_ref_temp expected to be temporary.";
- pp::FileRef file_ref_ext;
- std::string result = MakeExternalFileRef(&file_ref_ext);
- if (!result.empty())
- return result;
- PASS();
- }
- std::string TestFileRef::TestGetName() {
- pp::FileSystem file_system_pers(
- instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- pp::FileSystem file_system_temp(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
- std::string name = file_ref_pers.GetName().AsString();
- if (name != kPersFileName)
- return ReportMismatch("FileRef::GetName", name, kPersFileName);
- pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
- name = file_ref_temp.GetName().AsString();
- if (name != kTempFileName)
- return ReportMismatch("FileRef::GetName", name, kTempFileName);
- // Test the "/" case.
- pp::FileRef file_ref_slash(file_system_temp, "/");
- name = file_ref_slash.GetName().AsString();
- if (name != "/")
- return ReportMismatch("FileRef::GetName", name, "/");
- pp::FileRef file_ref_ext;
- std::string result = MakeExternalFileRef(&file_ref_ext);
- if (!result.empty())
- return result;
- name = file_ref_ext.GetName().AsString();
- ASSERT_FALSE(name.empty());
- PASS();
- }
- std::string TestFileRef::TestGetPath() {
- pp::FileSystem file_system_pers(
- instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- pp::FileSystem file_system_temp(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
- ASSERT_EQ(kPersFilePath, file_ref_pers.GetPath().AsString());
- pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
- ASSERT_EQ(kTempFilePath, file_ref_temp.GetPath().AsString());
- pp::FileRef file_ref_ext;
- std::string result = MakeExternalFileRef(&file_ref_ext);
- if (!result.empty())
- return result;
- ASSERT_TRUE(file_ref_ext.GetPath().is_undefined());
- PASS();
- }
- std::string TestFileRef::TestGetParent() {
- pp::FileSystem file_system_pers(
- instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- pp::FileSystem file_system_temp(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
- ASSERT_EQ(kParentPath, file_ref_pers.GetParent().GetPath().AsString());
- pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
- ASSERT_EQ(kParentPath, file_ref_temp.GetParent().GetPath().AsString());
- // Test the "/" case.
- pp::FileRef file_ref_slash(file_system_temp, "/");
- ASSERT_EQ("/", file_ref_slash.GetParent().GetPath().AsString());
- // Test the "/foo" case (the parent is "/").
- pp::FileRef file_ref_with_root_parent(file_system_temp, "/foo");
- ASSERT_EQ("/", file_ref_with_root_parent.GetParent().GetPath().AsString());
- pp::FileRef file_ref_ext;
- std::string result = MakeExternalFileRef(&file_ref_ext);
- if (!result.empty())
- return result;
- ASSERT_TRUE(file_ref_ext.GetParent().is_null());
- PASS();
- }
- std::string TestFileRef::TestMakeDirectory() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- // Open.
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Make a directory.
- pp::FileRef dir_ref(file_system, "/dir_make_dir");
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Make a directory on the existing path without exclusive flag.
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Making a directory should be aborted.
- int32_t rv = PP_ERROR_FAILED;
- {
- rv = pp::FileRef(file_system, "/dir_make_dir_abort")
- .MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback());
- }
- callback.WaitForAbortResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- // Make nested directories.
- dir_ref = pp::FileRef(file_system, "/dir_make_nested_dir_1/dir");
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- dir_ref = pp::FileRef(file_system, "/dir_make_nested_dir_2/dir");
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
- // Ensure there is no directory on the path to test exclusive cases.
- dir_ref = pp::FileRef(file_system, "/dir_make_dir_exclusive");
- rv = DeleteDirectoryRecursively(&dir_ref);
- ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND);
- // Make a directory exclusively.
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_EXCLUSIVE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- callback.WaitForResult(
- dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_EXCLUSIVE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_ERROR_FILEEXISTS, callback.result());
- PASS();
- }
- std::string TestFileRef::TestQueryAndTouchFile() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef file_ref(file_system, "/file_touch");
- pp::FileIO file_io(instance_);
- callback.WaitForResult(
- file_io.Open(file_ref,
- PP_FILEOPENFLAG_CREATE |
- PP_FILEOPENFLAG_TRUNCATE |
- PP_FILEOPENFLAG_WRITE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Write some data to have a non-zero file size.
- callback.WaitForResult(file_io.Write(0, "test", 4, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(4, callback.result());
- // Touch.
- const PP_Time last_access_time = 123 * 24 * 3600.0;
- // last_modified_time's granularity is 2 seconds
- // See note in test_file_io.cc for why we use this time.
- const PP_Time last_modified_time = 100 * 24 * 3600.0;
- callback.WaitForResult(file_ref.Touch(last_access_time, last_modified_time,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Touch aborted.
- int32_t rv = PP_ERROR_FAILED;
- {
- rv = pp::FileRef(file_system, "/file_touch_abort")
- .Touch(last_access_time, last_modified_time, callback.GetCallback());
- }
- callback.WaitForResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- if (rv == PP_OK_COMPLETIONPENDING) {
- // Touch tried to run asynchronously and should have been aborted.
- ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
- } else {
- // Touch ran synchronously and should have failed because the file does not
- // exist.
- ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
- }
- // Query.
- PP_FileInfo info;
- callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- ASSERT_EQ(4, info.size);
- ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
- ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
- // Disabled due to DST-related failure: crbug.com/314579
- // ASSERT_EQ(last_access_time, info.last_access_time);
- // ASSERT_EQ(last_modified_time, info.last_modified_time);
- // Cancellation test.
- // TODO(viettrungluu): this test causes a bunch of LOG(WARNING)s; investigate.
- // TODO(viettrungluu): check |info| for late writes.
- {
- rv = pp::FileRef(file_system, "/file_touch").Touch(
- last_access_time, last_modified_time, callback.GetCallback());
- }
- callback.WaitForAbortResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- PASS();
- }
- std::string TestFileRef::TestDeleteFileAndDirectory() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef file_ref(file_system, "/file_delete");
- pp::FileIO file_io(instance_);
- callback.WaitForResult(
- file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef dir_ref(file_system, "/dir_delete");
- callback.WaitForResult(dir_ref.MakeDirectory(
- PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- callback.WaitForResult(dir_ref.Delete(callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef nested_dir_ref(file_system, "/dir_delete_1/dir_delete_2");
- callback.WaitForResult(
- nested_dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Attempt to delete the parent directory (should fail; it's non-empty).
- pp::FileRef parent_dir_ref = nested_dir_ref.GetParent();
- callback.WaitForResult(parent_dir_ref.Delete(callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_ERROR_FAILED, callback.result());
- pp::FileRef nonexistent_file_ref(file_system, "/nonexistent_file_delete");
- callback.WaitForResult(nonexistent_file_ref.Delete(callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
- // Delete aborted.
- int32_t rv = PP_ERROR_FAILED;
- {
- pp::FileRef file_ref_abort(file_system, "/file_delete_abort");
- pp::FileIO file_io_abort(instance_);
- callback.WaitForResult(
- file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- rv = file_ref_abort.Delete(callback.GetCallback());
- }
- callback.WaitForAbortResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- PASS();
- }
- std::string TestFileRef::TestRenameFileAndDirectory() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef file_ref(file_system, "/file_rename");
- pp::FileIO file_io(instance_);
- callback.WaitForResult(
- file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef target_file_ref(file_system, "/target_file_rename");
- callback.WaitForResult(
- file_ref.Rename(target_file_ref, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef dir_ref(file_system, "/dir_rename");
- callback.WaitForResult(dir_ref.MakeDirectory(
- PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef target_dir_ref(file_system, "/target_dir_rename");
- callback.WaitForResult(
- dir_ref.Rename(target_dir_ref, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef nested_dir_ref(file_system, "/dir_rename_1/dir_rename_2");
- callback.WaitForResult(
- nested_dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Try to rename nested directory to the parent name. Should fail.
- pp::FileRef target_nested_dir_ref(file_system, "/dir_rename_1");
- callback.WaitForResult(
- nested_dir_ref.Rename(target_nested_dir_ref, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_ERROR_FAILED, callback.result());
- // Rename aborted.
- // TODO(viettrungluu): Figure out what we want to do if the target file
- // resource is destroyed before completion.
- int32_t rv = PP_ERROR_FAILED;
- pp::FileRef target_file_ref_abort(file_system,
- "/target_file_rename_abort");
- {
- pp::FileRef file_ref_abort(file_system, "/file_rename_abort");
- pp::FileIO file_io_abort(instance_);
- callback.WaitForResult(
- file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- rv = file_ref_abort.Rename(target_file_ref_abort, callback.GetCallback());
- }
- callback.WaitForAbortResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- PASS();
- }
- std::string TestFileRef::TestQuery() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- pp::FileRef file_ref(file_system, "/file");
- pp::FileIO file_io(instance_);
- callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE,
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // We touch the file so we can easily check access and modified time.
- callback.WaitForResult(file_io.Touch(0, 0, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- TestCompletionCallbackWithOutput<PP_FileInfo> out_callback(
- instance_->pp_instance(), callback_type());
- out_callback.WaitForResult(file_ref.Query(out_callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(out_callback);
- ASSERT_EQ(PP_OK, out_callback.result());
- PP_FileInfo info = out_callback.output();
- ASSERT_EQ(0, info.size);
- ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
- ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
- ASSERT_DOUBLE_EQ(0.0, info.last_access_time);
- ASSERT_DOUBLE_EQ(0.0, info.last_modified_time);
- // Query a file ref on an external filesystem.
- pp::FileRef file_ref_ext;
- std::string result = MakeExternalFileRef(&file_ref_ext);
- if (!result.empty())
- return result;
- out_callback.WaitForResult(file_ref_ext.Query(out_callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(out_callback);
- if (out_callback.result() != PP_OK)
- return ReportError("Query() result", out_callback.result());
- ASSERT_EQ(PP_OK, out_callback.result());
- info = out_callback.output();
- ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
- ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, info.system_type);
- // We can't touch the file, so just sanity check the times.
- ASSERT_TRUE(info.creation_time >= 0.0);
- ASSERT_TRUE(info.last_modified_time >= 0.0);
- ASSERT_TRUE(info.last_access_time >= 0.0);
- // Query a file ref for a file that doesn't exist.
- pp::FileRef missing_file_ref(file_system, "/missing_file");
- out_callback.WaitForResult(missing_file_ref.Query(
- out_callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(out_callback);
- ASSERT_EQ(PP_ERROR_FILENOTFOUND, out_callback.result());
- PASS();
- }
- std::string TestFileRef::TestFileNameEscaping() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- std::string test_dir_path = "/dir_for_escaping_test";
- // Create a directory in which to test.
- pp::FileRef test_dir_ref(file_system, test_dir_path.c_str());
- callback.WaitForResult(test_dir_ref.MakeDirectory(
- PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Create the file with the terrible name.
- std::string full_file_path = test_dir_path + "/" + kTerribleName;
- pp::FileRef file_ref(file_system, full_file_path.c_str());
- pp::FileIO file_io(instance_);
- callback.WaitForResult(
- file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // FileRef::ReadDirectoryEntries only works out-of-process.
- if (testing_interface_->IsOutOfProcess()) {
- TestCompletionCallbackWithOutput<DirEntries>
- output_callback(instance_->pp_instance(), callback_type());
- output_callback.WaitForResult(
- test_dir_ref.ReadDirectoryEntries(output_callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(output_callback);
- ASSERT_EQ(PP_OK, output_callback.result());
- DirEntries entries = output_callback.output();
- ASSERT_EQ(1, entries.size());
- ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString());
- }
- PASS();
- }
- std::string TestFileRef::TestReadDirectoryEntries() {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- pp::FileSystem file_system(
- instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
- callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- // Setup testing directories and files.
- const char* test_dir_name = "/test_get_next_file";
- const char* file_prefix = "file_";
- const char* dir_prefix = "dir_";
- pp::FileRef test_dir(file_system, test_dir_name);
- int32_t rv = DeleteDirectoryRecursively(&test_dir);
- ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND);
- callback.WaitForResult(test_dir.MakeDirectory(
- PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- static const int kNumFiles = 3;
- std::set<std::string> expected_file_names;
- for (int i = 1; i <= kNumFiles; ++i) {
- std::ostringstream buffer;
- buffer << test_dir_name << '/' << file_prefix << i;
- pp::FileRef file_ref(file_system, buffer.str().c_str());
- pp::FileIO file_io(instance_);
- callback.WaitForResult(
- file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- expected_file_names.insert(buffer.str());
- }
- static const int kNumDirectories = 3;
- std::set<std::string> expected_dir_names;
- for (int i = 1; i <= kNumDirectories; ++i) {
- std::ostringstream buffer;
- buffer << test_dir_name << '/' << dir_prefix << i;
- pp::FileRef file_ref(file_system, buffer.str().c_str());
- callback.WaitForResult(file_ref.MakeDirectory(
- PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- expected_dir_names.insert(buffer.str());
- }
- // Test that |ReadDirectoryEntries()| is able to fetch all
- // directories and files that we created.
- {
- TestCompletionCallbackWithOutput<DirEntries> output_callback(
- instance_->pp_instance(), callback_type());
- output_callback.WaitForResult(
- test_dir.ReadDirectoryEntries(output_callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(output_callback);
- ASSERT_EQ(PP_OK, output_callback.result());
- DirEntries entries = output_callback.output();
- size_t sum = expected_file_names.size() + expected_dir_names.size();
- ASSERT_EQ(sum, entries.size());
- for (DirEntries::const_iterator it = entries.begin();
- it != entries.end(); ++it) {
- pp::FileRef file_ref = it->file_ref();
- std::string file_path = file_ref.GetPath().AsString();
- std::set<std::string>::iterator found =
- expected_file_names.find(file_path);
- if (found != expected_file_names.end()) {
- if (it->file_type() != PP_FILETYPE_REGULAR)
- return file_path + " should have been a regular file.";
- expected_file_names.erase(found);
- } else {
- found = expected_dir_names.find(file_path);
- if (found == expected_dir_names.end())
- return "Unexpected file path: " + file_path;
- if (it->file_type() != PP_FILETYPE_DIRECTORY)
- return file_path + " should have been a directory.";
- expected_dir_names.erase(found);
- }
- }
- ASSERT_TRUE(expected_file_names.empty());
- ASSERT_TRUE(expected_dir_names.empty());
- }
- // Test cancellation of asynchronous |ReadDirectoryEntries()|.
- TestCompletionCallbackWithOutput<DirEntries> output_callback(
- instance_->pp_instance(), callback_type());
- {
- rv = pp::FileRef(file_system, test_dir_name)
- .ReadDirectoryEntries(output_callback.GetCallback());
- }
- output_callback.WaitForAbortResult(rv);
- CHECK_CALLBACK_BEHAVIOR(output_callback);
- PASS();
- }
|