diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-23 22:00:04 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-23 22:00:04 +0000 |
commit | b2f2308d0c635418caa3ad2a2560a2778d70a4d5 (patch) | |
tree | daaa5177eb28ddcb2d5582a4e78cf7b0318aea07 /ppapi | |
parent | 10b6e62953ff6ebc0ac9e7cb7628677da273f79b (diff) | |
download | chromium_src-b2f2308d0c635418caa3ad2a2560a2778d70a4d5.zip chromium_src-b2f2308d0c635418caa3ad2a2560a2778d70a4d5.tar.gz chromium_src-b2f2308d0c635418caa3ad2a2560a2778d70a4d5.tar.bz2 |
Fix PP_FileOpenFlags_Dev handling:
- rewrite the mapping from PP_FileOpenFlags_Dev to PlatformFileFlags.
- let ppb_flash_file_impl and ppb_file_io_impl use the same mapping logic.
- CreatePlatformFile: resolve the conflict between the win and posix implementation. Before this change, the win implementation didn't allow PLATFORM_FILE_TRUNCATE to be used with any of the (OPEN|CREATE)(_ALWAYS)? flags; while the posix implementation required it to be used with them.
- add more test cases to test the behavior of different PP_FileOpenFlags_Dev combinations.
- also unify the conversion from PlatformFileError to Pepper error.
BUG=68489
TEST=New test cases in test_file_io.cc
Review URL: http://codereview.chromium.org/7038032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86349 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/tests/test_file_io.cc | 220 | ||||
-rw-r--r-- | ppapi/tests/test_file_io.h | 28 | ||||
-rw-r--r-- | ppapi/tests/test_file_ref.cc | 4 |
3 files changed, 234 insertions, 18 deletions
diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc index 53a441b..423016a 100644 --- a/ppapi/tests/test_file_io.cc +++ b/ppapi/tests/test_file_io.cc @@ -29,6 +29,34 @@ std::string ReportMismatch(const std::string& method_name, expected_result + "' expected."; } +std::string ReportOpenError(int32_t open_flags) { + static const char* kFlagNames[] = { + "PP_FILEOPENFLAG_READ", + "PP_FILEOPENFLAG_WRITE", + "PP_FILEOPENFLAG_CREATE", + "PP_FILEOPENFLAG_TRUNCATE", + "PP_FILEOPENFLAG_EXCLUSIVE" + }; + + std::string result = "FileIO:Open had unexpected behavior with flags: "; + bool first_flag = true; + for (int32_t mask = 1, index = 0; mask <= PP_FILEOPENFLAG_EXCLUSIVE; + mask <<= 1, ++index) { + if (mask & open_flags) { + if (first_flag) { + first_flag = false; + } else { + result += " | "; + } + result += kFlagNames[index]; + } + } + if (first_flag) + result += "[None]"; + + return result; +} + int32_t ReadEntireFile(PP_Instance instance, pp::FileIO_Dev* file_io, int32_t offset, @@ -103,22 +131,87 @@ std::string TestFileIO::TestOpen() { if (rv != PP_OK) return ReportError("FileSystem::Open", rv); - pp::FileIO_Dev file_io(instance_); - rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback); - if (rv == PP_OK_COMPLETIONPENDING) - rv = callback.WaitForResult(); - if (rv != PP_OK) - return ReportError("FileIO::Open", rv); - - // Try opening a file that doesn't exist. - pp::FileRef_Dev nonexistent_file_ref(file_system, "/nonexistent_file"); - pp::FileIO_Dev nonexistent_file_io(instance_); - rv = nonexistent_file_io.Open( - nonexistent_file_ref, PP_FILEOPENFLAG_READ, callback); - if (rv == PP_OK_COMPLETIONPENDING) - rv = callback.WaitForResult(); - if (rv != PP_ERROR_FILENOTFOUND) - return ReportError("FileIO::Open", rv); + std::string result; + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_READ, + DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + // Test the behavior of the power set of + // { PP_FILEOPENFLAG_CREATE, + // PP_FILEOPENFLAG_TRUNCATE, + // PP_FILEOPENFLAG_EXCLUSIVE }. + + // First of all, none of them are specificed. + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE, + DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, + CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE, + DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE, + DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_EXCLUSIVE, + CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_TRUNCATE, + CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE | + PP_FILEOPENFLAG_TRUNCATE, + DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_EXCLUSIVE | PP_FILEOPENFLAG_TRUNCATE, + CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); + if (!result.empty()) + return result; + + // Invalid combination: PP_FILEOPENFLAG_TRUNCATE without + // PP_FILEOPENFLAG_WRITE. + result = MatchOpenExpectations( + &file_system, + PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_TRUNCATE, + INVALID_FLAG_COMBINATION); + if (!result.empty()) + return result; PASS(); } @@ -137,6 +230,7 @@ std::string TestFileIO::TestReadWriteSetLength() { pp::FileIO_Dev file_io(instance_); rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_TRUNCATE | PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE, callback); @@ -250,7 +344,9 @@ std::string TestFileIO::TestTouchQuery() { pp::FileRef_Dev file_ref(file_system, "/file_touch"); pp::FileIO_Dev file_io(instance_); rv = file_io.Open(file_ref, - PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_TRUNCATE | + PP_FILEOPENFLAG_WRITE, callback); if (rv == PP_OK_COMPLETIONPENDING) rv = callback.WaitForResult(); @@ -496,4 +592,94 @@ std::string TestFileIO::TestAbortCalls() { PASS(); } +std::string TestFileIO::MatchOpenExpectations(pp::FileSystem_Dev* file_system, + size_t open_flags, + size_t expectations) { + std::string bad_argument = + "TestFileIO::MatchOpenExpectations has invalid input arguments."; + bool invalid_combination = !!(expectations & INVALID_FLAG_COMBINATION); + if (invalid_combination) { + if (expectations != INVALID_FLAG_COMBINATION) + return bad_argument; + } else { + // Validate that one and only one of <some_expectation> and + // DONT_<some_expectation> is specified. + for (size_t remains = expectations, end = END_OF_OPEN_EXPECATION_PAIRS; + end != 0; remains >>= 2, end >>= 2) { + if (!!(remains & 1) == !!(remains & 2)) + return bad_argument; + } + } + bool create_if_doesnt_exist = !!(expectations & CREATE_IF_DOESNT_EXIST); + bool open_if_exists = !!(expectations & OPEN_IF_EXISTS); + bool truncate_if_exists = !!(expectations & TRUNCATE_IF_EXISTS); + + TestCompletionCallback callback(instance_->pp_instance()); + pp::FileRef_Dev existent_file_ref( + *file_system, "/match_open_expectation_existent_non_empty_file"); + pp::FileRef_Dev nonexistent_file_ref( + *file_system, "/match_open_expectation_nonexistent_file"); + + // Setup files for test. + { + int32_t rv = existent_file_ref.Delete(callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) + return ReportError("FileRef::Delete", rv); + + rv = nonexistent_file_ref.Delete(callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) + return ReportError("FileRef::Delete", rv); + + pp::FileIO_Dev existent_file_io(instance_); + rv = existent_file_io.Open(existent_file_ref, + PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, + callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + rv = WriteEntireBuffer(instance_->pp_instance(), &existent_file_io, 0, + "foobar"); + if (rv != PP_OK) + return ReportError("FileIO::Write", rv); + } + + pp::FileIO_Dev existent_file_io(instance_); + int32_t rv = existent_file_io.Open(existent_file_ref, open_flags, callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if ((invalid_combination && rv == PP_OK) || + (!invalid_combination && ((rv == PP_OK) != open_if_exists))) { + return ReportOpenError(open_flags); + } + + if (!invalid_combination && open_if_exists) { + PP_FileInfo_Dev info; + rv = existent_file_io.Query(&info, callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Query", rv); + + if (truncate_if_exists != (info.size == 0)) + return ReportOpenError(open_flags); + } + + pp::FileIO_Dev nonexistent_file_io(instance_); + rv = nonexistent_file_io.Open(nonexistent_file_ref, open_flags, callback); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + if ((invalid_combination && rv == PP_OK) || + (!invalid_combination && ((rv == PP_OK) != create_if_doesnt_exist))) { + return ReportOpenError(open_flags); + } + + return std::string(); +} + // TODO(viettrungluu): Test Close(). crbug.com/69457 diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h index 0140824..2d6117f 100644 --- a/ppapi/tests/test_file_io.h +++ b/ppapi/tests/test_file_io.h @@ -9,6 +9,10 @@ #include "ppapi/tests/test_case.h" +namespace pp { +class FileSystem_Dev; +} // namespace pp + class TestFileIO : public TestCase { public: explicit TestFileIO(TestingInstance* instance) : TestCase(instance) {} @@ -18,10 +22,34 @@ class TestFileIO : public TestCase { virtual void RunTest(); private: + enum OpenExpectation { + CREATE_IF_DOESNT_EXIST = 1 << 0, + DONT_CREATE_IF_DOESNT_EXIST = 1 << 1, + OPEN_IF_EXISTS = 1 << 2, + DONT_OPEN_IF_EXISTS = 1 << 3, + TRUNCATE_IF_EXISTS = 1 << 4, + DONT_TRUNCATE_IF_EXISTS = 1 << 5, + // All values above are defined in pairs: <some_expectation> and + // DONT_<some_expectation>. + END_OF_OPEN_EXPECATION_PAIRS = DONT_TRUNCATE_IF_EXISTS, + + INVALID_FLAG_COMBINATION = 1 << 6, + }; + std::string TestOpen(); std::string TestReadWriteSetLength(); std::string TestTouchQuery(); std::string TestAbortCalls(); + + // Helper method used by TestOpen(). + // |expectations| is a combination of OpenExpectation values. The followings + // are considered as valid input: + // 1) INVALID_FLAG_COMBINATION + // 2) (DONT_)?CREATE_IF_DOESNT_EXIST | (DONT_)?OPEN_IF_EXISTS | + // (DONT_)?TRUNCATE_IF_EXISTS + std::string MatchOpenExpectations(pp::FileSystem_Dev* file_system, + size_t open_flags, + size_t expectations); }; #endif // PAPPI_TESTS_TEST_FILE_IO_H_ diff --git a/ppapi/tests/test_file_ref.cc b/ppapi/tests/test_file_ref.cc index c448927..2fa8e5b 100644 --- a/ppapi/tests/test_file_ref.cc +++ b/ppapi/tests/test_file_ref.cc @@ -325,7 +325,9 @@ std::string TestFileRef::TestQueryAndTouchFile() { pp::FileRef_Dev file_ref(file_system, "/file_touch"); pp::FileIO_Dev file_io(instance_); rv = file_io.Open(file_ref, - PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_TRUNCATE | + PP_FILEOPENFLAG_WRITE, callback); if (rv == PP_OK_COMPLETIONPENDING) rv = callback.WaitForResult(); |