diff --git a/coding/coding_tests/file_data_test.cpp b/coding/coding_tests/file_data_test.cpp index ff7ea936e2..69a1511638 100644 --- a/coding/coding_tests/file_data_test.cpp +++ b/coding/coding_tests/file_data_test.cpp @@ -6,35 +6,48 @@ #include "../../base/logging.hpp" -UNIT_TEST(FileData_Api_Smoke) +namespace { - string name = "test.file"; - string newName = "new_test.file"; + string const name1 = "test1.file"; + string const name2 = "test2.file"; - try + void MakeFile(string const & name) { - // just create file and close it immediately my::FileData f(name, my::FileData::OP_WRITE_TRUNCATE); + f.Write(name.c_str(), name.size()); } - catch (Writer::OpenException const &) + + void CheckFileOK(string const & name) { - LOG(LCRITICAL, ("Can't create test file")); - return; + my::FileData f(name, my::FileData::OP_READ); + + uint64_t const size = f.Size(); + TEST_EQUAL ( size, name.size(), () ); + + vector buffer(size); + f.Read(0, &buffer[0], size); + TEST ( equal(name.begin(), name.end(), buffer.begin()), () ); } +} + +UNIT_TEST(FileData_ApiSmoke) +{ + MakeFile(name1); + uint64_t const size = name1.size(); uint64_t sz; - TEST_EQUAL(my::GetFileSize(name, sz), true, ()); - TEST_EQUAL(sz, 0, ()); + TEST(my::GetFileSize(name1, sz), ()); + TEST_EQUAL(sz, size, ()); - TEST_EQUAL(my::RenameFileX(name, newName), true, ()); + TEST(my::RenameFileX(name1, name2), ()); - TEST_EQUAL(my::GetFileSize(name, sz), false, ()); - TEST_EQUAL(my::GetFileSize(newName, sz), true, ()); - TEST_EQUAL(sz, 0, ()); + TEST(!my::GetFileSize(name1, sz), ()); + TEST(my::GetFileSize(name2, sz), ()); + TEST_EQUAL(sz, size, ()); - TEST_EQUAL(my::DeleteFileX(newName), true, ()); + TEST(my::DeleteFileX(name2), ()); - TEST_EQUAL(my::GetFileSize(newName, sz), false, ()); + TEST(!my::GetFileSize(name2, sz), ()); } /* @@ -58,3 +71,38 @@ UNIT_TEST(FileData_NoDiskSpace) (void)my::DeleteFileX(name); } */ + +#ifdef OMIM_OS_WINDOWS +UNIT_TEST(FileData_SharingAV_Windows) +{ + { + MakeFile(name1); + + // lock file, will check sharing access + my::FileData f1(name1, my::FileData::OP_READ); + + // try rename or delete locked file + TEST(!my::RenameFileX(name1, name2), ()); + TEST(!my::DeleteFileX(name1), ()); + + MakeFile(name2); + + // try rename or copy to locked file + TEST(!my::RenameFileX(name2, name1), ()); + TEST(!my::CopyFile(name2, name1), ()); + + // files should be unchanged + CheckFileOK(name1); + CheckFileOK(name2); + + //TEST(my::CopyFile(name1, name2), ()); + } + + // renaming to existing file is not allowed + TEST(!my::RenameFileX(name1, name2), ()); + TEST(!my::RenameFileX(name2, name1), ()); + + TEST(my::DeleteFileX(name1), ()); + TEST(my::DeleteFileX(name2), ()); +} +#endif diff --git a/coding/internal/file_data.cpp b/coding/internal/file_data.cpp index 10470d7f4d..d86113bca2 100644 --- a/coding/internal/file_data.cpp +++ b/coding/internal/file_data.cpp @@ -28,8 +28,9 @@ FileData::FileData(string const & fileName, Op op) #else m_File = fopen(fileName.c_str(), modes[op]); int error = m_File ? ferror(m_File) : 0; - if (m_File && !error) + if (m_File && error == 0) return; + if (op == OP_WRITE_EXISTING) { // Special case, since "r+b" fails if file doesn't exist. @@ -38,11 +39,12 @@ FileData::FileData(string const & fileName, Op op) m_File = fopen(fileName.c_str(), "wb"); error = m_File ? ferror(m_File) : 0; } - if (m_File && !error) + if (m_File && error == 0) return; #endif + // if we're here - something bad is happened - if (m_Op) + if (m_Op != OP_READ) MYTHROW(Writer::OpenException, (fileName, error)); else MYTHROW(Reader::OpenException, (fileName, error));