From 6718a736993ff2052acda09f324fe97edb0863d4 Mon Sep 17 00:00:00 2001 From: huangyuchen Date: Wed, 10 May 2023 17:18:52 +0800 Subject: [PATCH] Fix for codeCheck and cross-review comments. 1. Specially, remove the feature "Map when constructed", user should now call `Map()` manually after construction. 2. Add UT cases. Issue: I77T0Y Test: UT Signed-off-by: huangyuchen Change-Id: Ie27569e52f3349f70a34670b01dbd1c3f6f69e6a --- base/include/common_mapped_file_errors.h | 3 +- base/include/mapped_file.h | 15 +- base/src/mapped_file.cpp | 108 +++-- .../common/utils_mapped_file_test.cpp | 411 ++++++++++++++++-- 4 files changed, 427 insertions(+), 110 deletions(-) diff --git a/base/include/common_mapped_file_errors.h b/base/include/common_mapped_file_errors.h index f672aec..7174fb4 100644 --- a/base/include/common_mapped_file_errors.h +++ b/base/include/common_mapped_file_errors.h @@ -24,12 +24,11 @@ #define UTILS_COMMON_TIMER_ERRORS_H #include -#include "errors.h" #include "common_errors.h" +#include "errors.h" namespace OHOS { namespace Utils { - /** * ErrCode layout * diff --git a/base/include/mapped_file.h b/base/include/mapped_file.h index 0ccca64..2e6859d 100644 --- a/base/include/mapped_file.h +++ b/base/include/mapped_file.h @@ -23,8 +23,9 @@ #define UTILS_BASE_MAPPED_FILE_H #include -#include +#include #include +#include #include #include "errors.h" @@ -94,7 +95,7 @@ public: inline char* End() const { - return data_ == nullptr? nullptr : data_ + size_ - 1; + return data_ == nullptr ? nullptr : data_ + size_ - 1; } inline char* RegionStart() const @@ -149,9 +150,9 @@ private: return (input % PageSize() == 0) ? input : (input / PageSize() + 1) * PageSize(); } - bool ValidMappedSize(off_t &targetSize, const struct stat &stat); + bool ValidMappedSize(off_t& targetSize, const struct stat& stat); bool NormalizeSize(); - bool NormalizeMode(); + void NormalizeMode(); bool OpenFile(); bool SyncFileSize(off_t newSize); void Reset(); @@ -169,9 +170,9 @@ private: off_t offset_; MapMode mode_; int fd_ = -1; - int mapProt_; - int mapFlag_; - int openFlag_; + int mapProt_ = 0; + int mapFlag_ = 0; + int openFlag_ = 0; const char *hint_; }; diff --git a/base/src/mapped_file.cpp b/base/src/mapped_file.cpp index 594d9d4..12f1d8f 100644 --- a/base/src/mapped_file.cpp +++ b/base/src/mapped_file.cpp @@ -12,34 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "mapped_file.h" #include #include #include #include +#include "common_mapped_file_errors.h" #include "errors.h" #include "file_ex.h" #include "utils_log.h" -#include "common_mapped_file_errors.h" -#include "mapped_file.h" namespace OHOS { namespace Utils { off_t MappedFile::pageSize_ = static_cast(sysconf(_SC_PAGESIZE)); MappedFile::MappedFile(std::string& path, MapMode mode, off_t offset, off_t size, const char *hint) - :path_(path), size_(size), offset_(offset), mode_(mode), hint_(hint) -{ - if (Map() != MAPPED_FILE_ERR_OK) { - UTILS_LOGW("%{public}s: Mapping Failed.", __FUNCTION__); - } -} + :path_(path), size_(size), offset_(offset), mode_(mode), hint_(hint) {} -bool MappedFile::ValidMappedSize(off_t &targetSize, const struct stat &stb) +bool MappedFile::ValidMappedSize(off_t& targetSize, const struct stat& stb) { off_t max = RoundSize(stb.st_size) - offset_; // Avoid mapped size excessing - // that of the file more than a page, - if (max > 0) { // since write operation on it may raise signal 7. + // that of the file more than a page, + if (max > 0) { // since write operation on it may raise signal 7. targetSize = targetSize > max ? max : targetSize; } else { return false; @@ -51,7 +46,7 @@ bool MappedFile::ValidMappedSize(off_t &targetSize, const struct stat &stb) bool MappedFile::NormalizeSize() { if (size_ == 0 || size_ < DEFAULT_LENGTH) { - UTILS_LOGD("%{public}s: Failed. Invalid mapping size: %{public}lld", + UTILS_LOGE("%{public}s: Failed. Invalid mapping size: %{public}lld", __FUNCTION__, static_cast(size_)); return false; } @@ -59,7 +54,7 @@ bool MappedFile::NormalizeSize() errno = 0; if (!FileExists(path_)) { if ((mode_ & MapMode::CREATE_IF_ABSENT) == MapMode::DEFAULT) { - UTILS_LOGD("%{public}s: Failed. %{public}s", __FUNCTION__, strerror(errno)); + UTILS_LOGE("%{public}s: Failed. %{public}s", __FUNCTION__, strerror(errno)); return false; } @@ -82,7 +77,7 @@ bool MappedFile::NormalizeSize() // Get valid size if (!ValidMappedSize(size_, stb)) { - UTILS_LOGD("%{public}s: Failed. Invalid params. Specified size: %{public}lld, File size: %{public}lld", \ + UTILS_LOGE("%{public}s: Failed. Invalid params. Specified size: %{public}lld, File size: %{public}lld", \ __FUNCTION__, static_cast(size_), static_cast(stb.st_size)); return false; } @@ -91,7 +86,7 @@ bool MappedFile::NormalizeSize() return true; } -bool MappedFile::NormalizeMode() +void MappedFile::NormalizeMode() { mode_ &= (MapMode::PRIVATE | MapMode::READ_ONLY | MapMode::CREATE_IF_ABSENT); @@ -119,35 +114,30 @@ bool MappedFile::NormalizeMode() openFlag_ |= O_CREAT; } } - - return true; } ErrCode MappedFile::Normalize() { if (isNormed_) { - UTILS_LOGD("%{public}s: Failed. Already normalized.", __FUNCTION__); + UTILS_LOGD("%{public}s: Already normalized.", __FUNCTION__); return ERR_INVALID_OPERATION; } // resolve params for mapping region // offset if (offset_ < 0 || (offset_ % PageSize() != 0)) { - UTILS_LOGD("%{public}s: Failed. Invalid offset: %{public}lld", __FUNCTION__, static_cast(offset_)); + UTILS_LOGE("%{public}s: Failed. Invalid offset: %{public}lld", __FUNCTION__, static_cast(offset_)); return ERR_INVALID_VALUE; } // size if (!NormalizeSize()) { - UTILS_LOGD("%{public}s: Failed. Cannot normalize size.", __FUNCTION__); + UTILS_LOGE("%{public}s: Failed. Cannot normalize size.", __FUNCTION__); return ERR_INVALID_VALUE; } // Set open flags, mapping types and protections - if (!NormalizeMode()) { - UTILS_LOGD("%{public}s: Failed. Cannot normalize mode.", __FUNCTION__); - return ERR_INVALID_VALUE; - } + NormalizeMode(); isNormed_ = true; return MAPPED_FILE_ERR_OK; @@ -157,7 +147,7 @@ bool MappedFile::OpenFile() { int fd = open(path_.c_str(), openFlag_, S_IRWXU | S_IRGRP | S_IROTH); if (fd == -1) { - UTILS_LOGD("%{public}s: Failed. Cannot open file - %{public}s.", __FUNCTION__, strerror(errno)); + UTILS_LOGE("%{public}s: Failed. Cannot open file - %{public}s.", __FUNCTION__, strerror(errno)); return false; } @@ -222,11 +212,11 @@ ErrCode MappedFile::Map() } while (true); if (data == MAP_FAILED) { - UTILS_LOGD("%{public}s: Mapping Failed. %{public}s", __FUNCTION__, strerror(errno)); + UTILS_LOGE("%{public}s: Mapping Failed. %{public}s", __FUNCTION__, strerror(errno)); return MAPPED_FILE_ERR_FAILED; } - rStart_ = reinterpret_cast(data); + rStart_ = reinterpret_cast(data); // set region boundary. rEnd_ = rStart_ + (RoundSize(size_) - 1LL); // set segment start @@ -247,12 +237,6 @@ ErrCode MappedFile::Unmap() UTILS_LOGW("%{public}s. Try unmapping with params changed.", __FUNCTION__); } - if (reinterpret_cast(rStart_) % PageSize() != 0) { - UTILS_LOGD("%{public}s: Failed. Invalid addr. Region start addr: %{public}p", - __FUNCTION__, reinterpret_cast(rStart_)); - return ERR_INVALID_VALUE; - } - if (munmap(rStart_, static_cast(size_)) == -1) { UTILS_LOGD("%{public}s: Failed. %{public}s.", __FUNCTION__, strerror(errno)); return MAPPED_FILE_ERR_FAILED; @@ -275,10 +259,6 @@ bool MappedFile::SyncFileSize(off_t newSize) } else if (offset_ + newSize <= stb.st_size) { UTILS_LOGW("%{public}s: Failed. Unextend file size, no need to sync.", __FUNCTION__); } else { - if (fd_ == -1) { - UTILS_LOGD("%{public}s: Failed. Invalid fd.", __PRETTY_FUNCTION__); - return false; - } if (ftruncate(fd_, offset_ + newSize) == -1) { UTILS_LOGD("%{public}s: Failed. Cannot extend file size: %{public}s.", __FUNCTION__, strerror(errno)); return false; @@ -289,21 +269,28 @@ bool MappedFile::SyncFileSize(off_t newSize) return true; } - ErrCode MappedFile::Resize(off_t newSize, bool sync) { + if (newSize == DEFAULT_LENGTH) { + struct stat stb = {0}; + if (stat(path_.c_str(), &stb) != 0) { + UTILS_LOGW("%{public}s: Failed. Get file size failed! Mapped size will be that of a page.", __FUNCTION__); + newSize = PageSize(); + } + + if (newSize == DEFAULT_LENGTH) { + newSize = stb.st_size; + } + } + if (newSize == 0 || newSize < DEFAULT_LENGTH || newSize == size_) { UTILS_LOGD("%{public}s: Failed. Cannot remap with the same /negative size.", __FUNCTION__); return ERR_INVALID_OPERATION; } if (!isMapped_) { - UTILS_LOGD("%{public}s: Failed. Cannot remap with no mapped file exists.", __FUNCTION__); - return ERR_INVALID_OPERATION; - } - - if (!isNormed_) { - UTILS_LOGD("%{public}s: Failed. Cannot remap with params unnormalized.", __FUNCTION__); + UTILS_LOGD("%{public}s: Failed. Invalid status. mapped:%{public}d, normed:%{public}d", \ + __FUNCTION__, isMapped_, isNormed_); return ERR_INVALID_OPERATION; } @@ -365,11 +352,11 @@ ErrCode MappedFile::TurnNext() } struct stat stb = {0}; - if (stat(path_.c_str(), &stb) != 0) { + int ret = stat(path_.c_str(), &stb); + if (ret != 0) { UTILS_LOGD("%{public}s: Failed. Get file size failed.", __FUNCTION__); return MAPPED_FILE_ERR_FAILED; } - if (EndOffset() + 1 >= stb.st_size) { UTILS_LOGD("%{public}s: Failed. No contents remained.", __FUNCTION__); return ERR_INVALID_OPERATION; @@ -382,8 +369,9 @@ ErrCode MappedFile::TurnNext() // if mapped, rStart_ and rEnd_ are viable if (isMapped_) { + char* curEnd = End(); // case 1: remap needed - if (End() == rEnd_) { + if (curEnd == rEnd_) { // check if larger than exact file size. if (EndOffset() + 1 + size_ > stb.st_size) { size_ = stb.st_size - EndOffset() - 1; @@ -393,8 +381,11 @@ ErrCode MappedFile::TurnNext() offset_ += oldSize; ErrCode res = Unmap(); - if (res != MAPPED_FILE_ERR_OK || (res = Resize()) != MAPPED_FILE_ERR_OK) { - UTILS_LOGD("%{public}s Failed. Fail to UnMap/Resize.", __FUNCTION__); + if (res == MAPPED_FILE_ERR_OK) { + res = Resize(); + } + if (res != MAPPED_FILE_ERR_OK) { + UTILS_LOGE("%{public}s Failed. Fail to UnMap/Resize.", __FUNCTION__); // restore offset_ = oldOff; size_ = oldSize; @@ -405,10 +396,9 @@ ErrCode MappedFile::TurnNext() } // case 2: no need to remap, but to adjust boundary. - if (End() + oldSize > rEnd_) { // otherwise else keep original "size_" - size_ = rEnd_ - End(); + if (curEnd + oldSize > rEnd_) { // otherwise keep original "size_" + size_ = rEnd_ - curEnd; } - data_ += oldSize; offset_ += oldSize; return MAPPED_FILE_ERR_OK; @@ -445,7 +435,7 @@ ErrCode MappedFile::Clear(bool force) { if (isMapped_) { ErrCode res = Unmap(); - if (!force && res != MAPPED_FILE_ERR_OK && res != ERR_INVALID_OPERATION) { + if (!force && res != MAPPED_FILE_ERR_OK) { UTILS_LOGD("%{public}s failed. UnMapping Failed.", __FUNCTION__); return res; } @@ -464,14 +454,14 @@ MappedFile::~MappedFile() { if (isMapped_) { ErrCode res = Unmap(); - if (res != MAPPED_FILE_ERR_OK && res != ERR_INVALID_OPERATION) { + if (res != MAPPED_FILE_ERR_OK) { UTILS_LOGW("%{public}s: File unmapping failed, it will be automatically \ unmapped when the process is terminated.", __FUNCTION__); } } if (fd_ != -1 && close(fd_) == -1) { - UTILS_LOGW("%{public}s: Failed. Cannot close the file: %{public}s.", \ + UTILS_LOGE("%{public}s: Failed. Cannot close the file: %{public}s.", \ __FUNCTION__, strerror(errno)); } } @@ -518,9 +508,9 @@ bool MappedFile::ChangeOffset(off_t val) isNormed_ = false; return true; - } else { - UTILS_LOGW("%{public}s: Change params failed. Unmapping failed.", __FUNCTION__); } + + UTILS_LOGW("%{public}s: Change params failed. Unmapping failed.", __FUNCTION__); } return false; } @@ -533,9 +523,9 @@ bool MappedFile::ChangeSize(off_t val) isNormed_ = false; return true; - } else { - UTILS_LOGW("%{public}s: Change params failed. Unmapping failed.", __FUNCTION__); } + + UTILS_LOGW("%{public}s: Change params failed. Unmapping failed.", __FUNCTION__); } return false; } diff --git a/base/test/unittest/common/utils_mapped_file_test.cpp b/base/test/unittest/common/utils_mapped_file_test.cpp index 8974133..765ba6a 100644 --- a/base/test/unittest/common/utils_mapped_file_test.cpp +++ b/base/test/unittest/common/utils_mapped_file_test.cpp @@ -12,17 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "mapped_file.h" +#include #include +#include #include #include -#include -#include +#include "common_mapped_file_errors.h" +#include "directory_ex.h" #include "errors.h" #include "file_ex.h" -#include "directory_ex.h" -#include "common_mapped_file_errors.h" -#include "mapped_file.h" using namespace testing::ext; using namespace OHOS::Utils; @@ -127,6 +127,7 @@ HWTEST_F(UtilsMappedFileTest, testDefaultMapping001, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // check status ASSERT_TRUE(mf.IsMapped()); @@ -145,8 +146,7 @@ HWTEST_F(UtilsMappedFileTest, testDefaultMapping001, TestSize.Level0) // 3. read from mapped file std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -191,6 +191,7 @@ HWTEST_F(UtilsMappedFileTest, testNewSharedMappingDefaultSize001, TestSize.Level // 2. map file MappedFile mf(filename, MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // check if file is created ASSERT_TRUE(FileExists(filename)); @@ -225,8 +226,7 @@ HWTEST_F(UtilsMappedFileTest, testNewSharedMappingDefaultSize001, TestSize.Level std::string toRead("Waiting to be read."); SaveStringToFile(filename, toRead, 0, true); std::string readout; - char* cur = mf.Begin(); - for (; *cur != '\0'; cur++) { + for (char* cur = mf.Begin(); *cur != '\0'; cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, toRead); @@ -245,12 +245,14 @@ HWTEST_F(UtilsMappedFileTest, testNewSharedMapping001, TestSize.Level0) RemoveTestFile(filename); // set params - char* hint = reinterpret_cast(0x80000); // new mapping region will not guaranteed to be located at `hint` + // new mapping region will not guaranteed to be located at `hint` + char* hint = reinterpret_cast(0x80000); // 0x80000: hint(expected address). off_t size = 1024; off_t offset = 4 * 1024; // 1. map a non-existed file MappedFile mf(filename, MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT, offset, size, hint); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // check if file is created ASSERT_TRUE(FileExists(filename)); @@ -262,8 +264,8 @@ HWTEST_F(UtilsMappedFileTest, testNewSharedMapping001, TestSize.Level0) // check specified size struct stat stb = {0}; if (stat(filename.c_str(), &stb) == 0) { - EXPECT_EQ(stb.st_size, offset + size); // Exact file size should be offset + mapped size, contents will be - // zero-filled. + // Exact file size should be offset + mapped size, contents will be zero-filled. + EXPECT_EQ(stb.st_size, offset + size); } ASSERT_EQ(mf.Size(), size); @@ -290,8 +292,7 @@ HWTEST_F(UtilsMappedFileTest, testNewSharedMapping001, TestSize.Level0) std::string toRead("Waiting to be read."); SaveStringToFile(filename, toRead, offset, true); std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End() && *cur != '\0'; cur++) { + for (char* cur = mf.Begin(); cur <= mf.End() && *cur != '\0'; cur++) { readout.push_back(*cur); } std::cout << "Read finished" << std::endl; @@ -316,6 +317,7 @@ HWTEST_F(UtilsMappedFileTest, testPrivateMapping001, TestSize.Level0) // 2. map file MappedFile mf(filename, MapMode::DEFAULT | MapMode::PRIVATE); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status ASSERT_TRUE(mf.IsMapped()); @@ -323,8 +325,7 @@ HWTEST_F(UtilsMappedFileTest, testPrivateMapping001, TestSize.Level0) // 4. read from mapped file std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -359,6 +360,7 @@ HWTEST_F(UtilsMappedFileTest, testSharedReadOnlyMapping001, TestSize.Level0) // 2. map file MappedFile mf(filename, MapMode::DEFAULT | MapMode::READ_ONLY); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status ASSERT_TRUE(mf.IsMapped()); @@ -366,8 +368,7 @@ HWTEST_F(UtilsMappedFileTest, testSharedReadOnlyMapping001, TestSize.Level0) // 4. read from mapped file std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -392,6 +393,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap001, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -414,7 +416,6 @@ HWTEST_F(UtilsMappedFileTest, testReMap001, TestSize.Level0) stat(filename.c_str(), &stb); EXPECT_TRUE(stb.st_size == mf.Size() || mf.PageSize() == mf.Size()); - RemoveTestFile(filename); } @@ -438,9 +439,21 @@ HWTEST_F(UtilsMappedFileTest, testReMap002, TestSize.Level0) ASSERT_TRUE(CreateTestFile(filename, content)); ASSERT_TRUE(CreateTestFile(filename1, content1)); - // 2. map file MappedFile mf(filename); + // Change params when unmapped. + ASSERT_TRUE(mf.ChangeSize(mf.Size() + 1024)); + ASSERT_TRUE(mf.ChangeSize(MappedFile::DEFAULT_LENGTH)); + ASSERT_TRUE(mf.ChangeOffset(mf.PageSize())); + ASSERT_TRUE(mf.ChangeOffset(0)); + ASSERT_TRUE(mf.ChangePath(filename1)); + ASSERT_TRUE(mf.ChangePath(filename)); + ASSERT_TRUE(mf.ChangeHint(reinterpret_cast(0x89000))); // 0x89000: random address. + ASSERT_TRUE(mf.ChangeMode(MapMode::READ_ONLY)); + + // 2. map file + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); ASSERT_TRUE(mf.IsNormed()); @@ -452,15 +465,16 @@ HWTEST_F(UtilsMappedFileTest, testReMap002, TestSize.Level0) // 5. read from Mapped File std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); // 6. change params - mf.ChangePath(filename1); - mf.ChangeSize(MappedFile::DEFAULT_LENGTH); + ASSERT_TRUE(mf.ChangePath(filename1)); + ASSERT_TRUE(mf.ChangeSize(MappedFile::DEFAULT_LENGTH)); + ASSERT_TRUE(mf.ChangeHint(reinterpret_cast(0x80000))); // 0x80000: random address. + ASSERT_TRUE(mf.ChangeMode(MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT)); // 7. check status after changing EXPECT_FALSE(mf.IsMapped()); @@ -478,8 +492,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap002, TestSize.Level0) // 11. read from Mapped File std::string readout1; - char* cur1 = mf.Begin(); - for (; cur1 <= mf.End(); cur1++) { + for (char* cur1 = mf.Begin(); cur1 <= mf.End(); cur1++) { readout1.push_back(*cur1); } EXPECT_EQ(readout1, content1); @@ -510,6 +523,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap003, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -522,8 +536,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap003, TestSize.Level0) // 5. read from Mapped File std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -548,8 +561,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap003, TestSize.Level0) // 11. read from Mapped File std::string readout1; - char* cur1 = mf.Begin(); - for (; cur1 <= mf.End(); cur1++) { + for (char* cur1 = mf.Begin(); cur1 <= mf.End(); cur1++) { readout1.push_back(*cur1); } EXPECT_EQ(readout1, content1); @@ -574,6 +586,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap004, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -630,6 +643,7 @@ HWTEST_F(UtilsMappedFileTest, testReMap005, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -667,6 +681,46 @@ HWTEST_F(UtilsMappedFileTest, testReMap005, TestSize.Level0) EXPECT_STREQ(res.c_str(), content.append("E").c_str()); // Changes will be sync in the original file. } +/* + * @tc.name: testReMap006 + * @tc.desc: Test remapping to via Resize(off_t, bool). + */ +HWTEST_F(UtilsMappedFileTest, testReMap006, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_remap.txt"; + std::string content = "Test for remapping use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + off_t size = 20; + MappedFile mf(filename, MapMode::DEFAULT, 0, size); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 3. check status after mapping + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 4. check size + ASSERT_TRUE(size == mf.Size()); + + // 5. remap to extend region + ASSERT_EQ(mf.Resize(MappedFile::DEFAULT_LENGTH, true), MAPPED_FILE_ERR_OK); + off_t lessSize = mf.Size() - 8; + ASSERT_EQ(mf.Resize(lessSize, true), MAPPED_FILE_ERR_OK); + // check status after remapping + EXPECT_TRUE(mf.IsMapped()); + EXPECT_TRUE(mf.IsNormed()); + + // 6. check size after remapping + struct stat stb = {0}; + stat(filename.c_str(), &stb); + EXPECT_EQ(lessSize, mf.Size()); +} + /* * @tc.name: testTurnNext001 * @tc.desc: Test TurnNext() when `IsMapped()`. @@ -683,15 +737,16 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext001, TestSize.Level0) struct stat stb = {0}; ASSERT_EQ(stat(filename.c_str(), &stb), 0); - off_t orig = stb.st_size; // 25 bit + off_t orig = stb.st_size; // 23 bytes // 2. extend its size int fd = open(filename.c_str(), O_RDWR | O_CLOEXEC); ASSERT_NE(fd, -1); - ASSERT_EQ(ftruncate(fd, MappedFile::PageSize() + MappedFile::PageSize() / 100LL), 0); + ASSERT_EQ(ftruncate(fd, MappedFile::PageSize() + MappedFile::PageSize() / 100LL), 0); // 100: ratio to a page. // 3. map file MappedFile mf(filename, MapMode::DEFAULT, 0, orig); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 4. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -708,7 +763,8 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext001, TestSize.Level0) off_t endOff; // 6. keep turnNext within a page - for (unsigned int cnt = 2; cnt < (MappedFile::PageSize() / orig); cnt++) { + for (unsigned int cnt = 2; cnt < (MappedFile::PageSize() / orig); cnt++) { // 2: start from 2 to take the first + // TunrNext() calling in consideration. endOff = mf.EndOffset(); EXPECT_EQ(mf.TurnNext(), MAPPED_FILE_ERR_OK); EXPECT_EQ(mf.StartOffset(), endOff + 1); @@ -769,6 +825,7 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext002, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); off_t curSize = mf.Size(); off_t curOff = mf.StartOffset(); @@ -803,6 +860,7 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext003, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -844,6 +902,7 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext004, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status after mapping ASSERT_TRUE(mf.IsMapped()); @@ -855,6 +914,74 @@ HWTEST_F(UtilsMappedFileTest, testTurnNext004, TestSize.Level0) RemoveTestFile(filename); } +/* + * @tc.name: testTurnNext005 + * @tc.desc: Test TurnNext() with file size less than one page. + */ +HWTEST_F(UtilsMappedFileTest, testTurnNext005, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_remap.txt"; + std::string content = "Test for remapping use.00"; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + struct stat stb = {0}; + ASSERT_EQ(stat(filename.c_str(), &stb), 0); + off_t orig = stb.st_size; // 25 bytes + + // 2. extend its size + int fd = open(filename.c_str(), O_RDWR | O_CLOEXEC); + ASSERT_NE(fd, -1); + ASSERT_EQ(ftruncate(fd, MappedFile::PageSize() + 10), 0); // 10: remain contents less than 25bits. + + // 3. map file + MappedFile mf(filename, MapMode::DEFAULT, 0, orig); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 4. check status after mapping + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 5. turn next mapped region with the same size as the file's initial size. + EXPECT_EQ(mf.TurnNext(), MAPPED_FILE_ERR_OK); + + off_t endOff; + // 6. keep turnNext within a page + for (unsigned int cnt = 2; cnt < (MappedFile::PageSize() / orig); cnt++) { // 2: start from 2 to take the first + // TunrNext() calling in consideration. + endOff = mf.EndOffset(); + EXPECT_EQ(mf.TurnNext(), MAPPED_FILE_ERR_OK); + EXPECT_EQ(mf.StartOffset(), endOff + 1); + EXPECT_EQ(mf.Size(), orig); + } + std::cout << "==Last TurnNext() with The Same Size==" << std::endl; + PrintStatus(mf); + + // 7. this turn will reach the bottom of a page + endOff = mf.EndOffset(); + char* rEnd = mf.RegionEnd(); + char* end = mf.End(); + EXPECT_EQ(mf.TurnNext(), MAPPED_FILE_ERR_OK); + EXPECT_EQ(mf.StartOffset(), endOff + 1); + EXPECT_EQ(mf.Size(), static_cast(rEnd - end)); + std::cout << "==Reached Bottom of A Page==" << std::endl; + PrintStatus(mf); + + // 8. this turn will trigger a remapping + endOff = mf.EndOffset(); + EXPECT_EQ(mf.TurnNext(), MAPPED_FILE_ERR_OK); + EXPECT_TRUE(mf.IsMapped()); + EXPECT_EQ(mf.StartOffset(), endOff + 1); + EXPECT_EQ(mf.Size(), 10); + EXPECT_EQ(mf.RegionStart(), mf.Begin()); + EXPECT_EQ(static_cast(mf.RegionEnd() - mf.RegionStart()) + 1LL, mf.PageSize()); + std::cout << "==Remap A New Page==" << std::endl; + PrintStatus(mf); +} + /* * @tc.name: testInvalidMap001 * @tc.desc: Test file mapping with invalid offset. @@ -872,10 +999,16 @@ HWTEST_F(UtilsMappedFileTest, testInvalidMap001, TestSize.Level0) // 2. map file off_t offset = 100; // Specify offset that is not multiple of page-size. MappedFile mf(filename, MapMode::DEFAULT, offset); + ASSERT_NE(mf.Map(), MAPPED_FILE_ERR_OK); + + MappedFile mf1(filename, MapMode::DEFAULT, -1); + ASSERT_NE(mf1.Map(), MAPPED_FILE_ERR_OK); // 3. check status EXPECT_FALSE(mf.IsMapped()); EXPECT_FALSE(mf.IsNormed()); // mapping will fail in normalize stage. + EXPECT_FALSE(mf1.IsMapped()); + EXPECT_FALSE(mf1.IsNormed()); // mapping will fail in normalize stage. RemoveTestFile(filename); } @@ -897,6 +1030,7 @@ HWTEST_F(UtilsMappedFileTest, testInvalidMap002, TestSize.Level0) // 2. map file off_t offset = 4 * 1024; // Specify offset excessing the substantial size of the file. MappedFile mf(filename, MapMode::DEFAULT, offset); + ASSERT_NE(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status EXPECT_FALSE(mf.IsMapped()); @@ -918,6 +1052,7 @@ HWTEST_F(UtilsMappedFileTest, testInvalidMap003, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_NE(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status EXPECT_FALSE(mf.IsMapped()); @@ -926,6 +1061,194 @@ HWTEST_F(UtilsMappedFileTest, testInvalidMap003, TestSize.Level0) RemoveTestFile(filename); } +/* + * @tc.name: testInvalidMap004 + * @tc.desc: Test mapping with invalid size. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap004, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_4.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + MappedFile mf(filename, MapMode::DEFAULT, 0, -2); // -2: less than DEFAULT_LENGTH(-1) + ASSERT_EQ(mf.Map(), ERR_INVALID_VALUE); + + // 3. map again with another invalid param. + MappedFile mf1(filename, MapMode::DEFAULT, 0, 0); + ASSERT_EQ(mf1.Map(), ERR_INVALID_VALUE); + + // 3. check status + EXPECT_FALSE(mf.IsMapped()); + EXPECT_FALSE(mf.IsNormed()); // mapping will fail in normalize stage. + EXPECT_FALSE(mf1.IsMapped()); + EXPECT_FALSE(mf1.IsNormed()); // mapping will fail in normalize stage. + + RemoveTestFile(filename); +} + +/* + * @tc.name: testInvalidMap005 + * @tc.desc: Test mapping an already mapped file. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap005, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_6.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + ASSERT_EQ(mf.Map(), ERR_INVALID_OPERATION); // Map again. + + // 3. check status + EXPECT_TRUE(mf.IsMapped()); + EXPECT_TRUE(mf.IsNormed()); + + RemoveTestFile(filename); +} + +/* + * @tc.name: testInvalidMap006 + * @tc.desc: Test resize with invalid params. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap006, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_7.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 3. check status + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 4. resize + EXPECT_EQ(mf.Resize(0), ERR_INVALID_OPERATION); + EXPECT_EQ(mf.Resize(-2), ERR_INVALID_OPERATION); // -2: less than DEFAULT_LENGTH(-1). + EXPECT_EQ(mf.Resize(mf.Size()), ERR_INVALID_OPERATION); + + // 5. Unmap first then resize. + ASSERT_EQ(mf.Unmap(), MAPPED_FILE_ERR_OK); + EXPECT_EQ(mf.Resize(mf.Size() + 8), ERR_INVALID_OPERATION); + + RemoveTestFile(filename); +} + +/* + * @tc.name: testInvalidMap007 + * @tc.desc: Test resize with no param changed. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap007, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_8.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 3. check status + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 4. resize + EXPECT_EQ(mf.Resize(), ERR_INVALID_OPERATION); + + RemoveTestFile(filename); +} + +/* + * @tc.name: testInvalidMap008 + * @tc.desc: Test TurnNext() with params changed. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap008, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_9.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. map file + MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 3. check status + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 5. Change params + ASSERT_TRUE(mf.ChangeSize(mf.Size() + 1)); + + // 6. check status + ASSERT_FALSE(mf.IsMapped()); + ASSERT_FALSE(mf.IsNormed()); + + // 4. turn next. + EXPECT_EQ(mf.TurnNext(), ERR_INVALID_OPERATION); + + RemoveTestFile(filename); +} + +/* + * @tc.name: testInvalidMap009 + * @tc.desc: Test ChangeXX() with invalid params. + */ +HWTEST_F(UtilsMappedFileTest, testInvalidMap009, TestSize.Level0) +{ + // 1. create a new file + std::string filename = "test_invalid_10.txt"; + std::string content = "Test for invalid use."; + filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); + RemoveTestFile(filename); + + ASSERT_TRUE(CreateTestFile(filename, content)); + + // 2. create MappedFile + MappedFile mf(filename); + + // 3. map file + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); + + // 4. check status + ASSERT_TRUE(mf.IsMapped()); + ASSERT_TRUE(mf.IsNormed()); + + // 5. Change params + ASSERT_FALSE(mf.ChangeOffset(mf.StartOffset())); + ASSERT_FALSE(mf.ChangeSize(mf.Size())); + ASSERT_FALSE(mf.ChangeHint(mf.GetHint())); + ASSERT_FALSE(mf.ChangeMode(mf.GetMode())); + ASSERT_FALSE(mf.ChangePath(mf.GetPath())); + + RemoveTestFile(filename); +} + /* * @tc.name: testAutoAdjustedMode001 * @tc.desc: Test mapping file with invalid mapping mode, but can be auto adjusted. @@ -944,6 +1267,7 @@ HWTEST_F(UtilsMappedFileTest, testAutoAdjustedMode001, TestSize.Level0) MapMode mode = static_cast(1) | static_cast(16) | MapMode::PRIVATE | MapMode::READ_ONLY; // bits out of the scope will be ignored. MappedFile mf(filename, mode); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status EXPECT_TRUE(mf.IsMapped()); @@ -972,6 +1296,7 @@ HWTEST_F(UtilsMappedFileTest, testAutoAdjustedSize001, TestSize.Level0) // 2. map file off_t size = 5 * 1024; // Specified size excessing the last page of the file. MappedFile mf(filename, MapMode::DEFAULT, 0, size); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 3. check status EXPECT_TRUE(mf.IsMapped()); @@ -1010,6 +1335,7 @@ HWTEST_F(UtilsMappedFileTest, testAutoAdjustedSize002, TestSize.Level0) off_t offset = 4 * 1024; off_t size = 5 * 1024; // Specified size excessing the last page of the file. MappedFile mf(filename, MapMode::DEFAULT, offset, size); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 4. check status EXPECT_TRUE(mf.IsMapped()); @@ -1043,6 +1369,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile001, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); off_t size = mf.Size(); off_t offset = mf.StartOffset(); @@ -1074,8 +1401,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile001, TestSize.Level0) // 5. read from mapped file std::string readout; - char* cur = mfNew.Begin(); - for (; cur <= mfNew.End(); cur++) { + for (char* cur = mfNew.Begin(); cur <= mfNew.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -1110,6 +1436,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile002, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); off_t size = mf.Size(); off_t offset = mf.StartOffset(); @@ -1143,8 +1470,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile002, TestSize.Level0) ASSERT_EQ(mfNew.Map(), MAPPED_FILE_ERR_OK); // 6. read from mapped file std::string readout; - char* cur = mfNew.Begin(); - for (; cur <= mfNew.End(); cur++) { + for (char* cur = mfNew.Begin(); cur <= mfNew.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content); @@ -1185,7 +1511,9 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile003, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); MappedFile mf1(filename1); + ASSERT_EQ(mf1.Map(), MAPPED_FILE_ERR_OK); off_t size = mf1.Size(); off_t offset = mf1.StartOffset(); @@ -1208,8 +1536,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile003, TestSize.Level0) // 5. read from mapped file std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content1); @@ -1251,7 +1578,9 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile004, TestSize.Level0) // 2. map file MappedFile mf(filename); + ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); MappedFile mf1(filename1); + ASSERT_EQ(mf1.Map(), MAPPED_FILE_ERR_OK); off_t size = mf1.Size(); off_t offset = mf1.StartOffset(); @@ -1275,8 +1604,7 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile004, TestSize.Level0) ASSERT_EQ(mf.Map(), MAPPED_FILE_ERR_OK); // 6. read from mapped file std::string readout; - char* cur = mf.Begin(); - for (; cur <= mf.End(); cur++) { + for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { readout.push_back(*cur); } EXPECT_EQ(readout, content1); @@ -1296,6 +1624,5 @@ HWTEST_F(UtilsMappedFileTest, testMoveMappedFile004, TestSize.Level0) RemoveTestFile(filename1); } - } // namespace } // namespace OHOS \ No newline at end of file -- Gitee