1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <benchmark/benchmark.h>
17 #include "mapped_file.h"
18 #include <fstream>
19 #include <iostream>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include "common_mapped_file_errors.h"
23 #include "directory_ex.h"
24 #include "errors.h"
25 #include "file_ex.h"
26 #include "benchmark_log.h"
27 #include "benchmark_assert.h"
28 using namespace OHOS::Utils;
29 
30 namespace OHOS {
31 namespace {
32 
33 static constexpr char BASE_PATH[] = "/data/test/commonlibrary_c_utils/";
34 static constexpr char SUITE_PATH[] = "mapped_file/";
35 const int CONSTANT_ZERO = 0;
36 
37 class BenchmarkMappedFileTest : public benchmark::Fixture {
38 public:
BenchmarkMappedFileTest()39     BenchmarkMappedFileTest()
40     {
41         Iterations(iterations);
42         Repetitions(repetitions);
43         ReportAggregatesOnly();
44     }
45 
46     ~BenchmarkMappedFileTest() override = default;
SetUp(const::benchmark::State & state)47     void SetUp(const ::benchmark::State& state) override
48     {
49         std::string dir = std::string(BASE_PATH).append(SUITE_PATH);
50         if (ForceCreateDirectory(dir)) {
51             BENCHMARK_LOGD("Create test dir: %{public}s", dir.c_str());
52         } else {
53             BENCHMARK_LOGD("Create test dir Failed: %{public}s", dir.c_str());
54         }
55     }
56 
TearDown(const::benchmark::State & state)57     void TearDown(const ::benchmark::State& state) override
58     {
59         if (ForceRemoveDirectory(std::string(BASE_PATH))) {
60             BENCHMARK_LOGD("Remove test dir: %{public}s", BASE_PATH);
61         }
62     }
63 
64 protected:
65     const int32_t repetitions = 3;
66     const int32_t iterations = 1000;
67 };
68 
PrintStatus(MappedFile & mf)69 void PrintStatus(MappedFile& mf)
70 {
71     BENCHMARK_LOGD("MappedFileTest void PrintStatus is called.");
72     BENCHMARK_LOGD("Mapped Region Start: %{public}p\n"
73                    "Mapped Region End: %{public}p\n"
74                    "View start: %{public}p\n"
75                    "View End: %{public}p\n",
76                    reinterpret_cast<void*>(mf.RegionStart()),
77                    reinterpret_cast<void*>(mf.RegionEnd()),
78                    reinterpret_cast<void*>(mf.Begin()),
79                    reinterpret_cast<void*>(mf.End()));
80 }
81 
CreateTestFile(const std::string & path,const std::string & content)82 bool CreateTestFile(const std::string& path, const std::string& content)
83 {
84     BENCHMARK_LOGD("MappedFileTest bool CreateTestFile is called.");
85     std::ofstream out(path, std::ios_base::out | std::ios_base::trunc);
86     if (out.is_open()) {
87         out << content.c_str();
88         return true;
89     }
90 
91     return false;
92 }
93 
RemoveTestFile(const std::string & path)94 int RemoveTestFile(const std::string& path)
95 {
96     BENCHMARK_LOGD("MappedFileTest int RemoveTestFile is called.");
97     return unlink(path.c_str());
98 }
99 
SaveStringToFile(const std::string & filePath,const std::string & content,off_t offset,bool truncated)100 bool SaveStringToFile(const std::string& filePath, const std::string& content, off_t offset, bool truncated /*= true*/)
101 {
102     BENCHMARK_LOGD("MappedFileTest bool SaveStringToFile is called.");
103     if (content.empty()) {
104         return true;
105     }
106 
107     std::ofstream file;
108     if (truncated) {
109         file.open(filePath.c_str(), std::ios::out | std::ios::trunc);
110     } else {
111         file.open(filePath.c_str(), std::ios::out | std::ios::app);
112     }
113 
114     if (!file.is_open()) {
115         return false;
116     }
117 
118     file.seekp(offset, std::ios::beg);
119 
120     file.write(content.c_str(), content.length());
121     if (file.fail()) {
122         return false;
123     }
124     return true;
125 }
126 
CreateFile(std::string & filename,std::string & content,benchmark::State & state)127 void CreateFile(std::string& filename, std::string& content, benchmark::State& state)
128 {
129     filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
130     RemoveTestFile(filename);
131 
132     AssertTrue((CreateTestFile(filename, content)),
133         "CreateTestFile(filename, content) did not equal true as expected.", state);
134 }
135 
ReadFromMappedFile(std::string & content,MappedFile & mf,benchmark::State & state)136 void ReadFromMappedFile(std::string& content, MappedFile& mf, benchmark::State& state)
137 {
138     std::string readout;
139     for (char* cur = mf.Begin(); cur <= mf.End(); cur++) {
140         readout.push_back(*cur);
141     }
142     AssertEqual(readout, content, "readout did not equal content as expected.", state);
143 }
144 
WriteToMappedFile(std::string & toWrite,MappedFile & mf)145 void WriteToMappedFile(std::string& toWrite, MappedFile& mf)
146 {
147     char* newCur = mf.Begin();
148     for (std::string::size_type i = 0; i < toWrite.length(); i++) {
149         (*newCur) = toWrite[i];
150         newCur++;
151     }
152 }
153 
154 /*
155  * @tc.name: testDefaultMapping001
156  * @tc.desc: Test file mapping with default params.
157  */
BENCHMARK_F(BenchmarkMappedFileTest,testDefaultMapping001)158 BENCHMARK_F(BenchmarkMappedFileTest, testDefaultMapping001)(benchmark::State& state)
159 {
160     BENCHMARK_LOGD("MappedFileTest testDefaultMapping001 start.");
161     while (state.KeepRunning()) {
162         // 1. Create a new file
163         std::string filename = "test_read_write_1.txt";
164         std::string content = "Test for normal use.";
165         CreateFile(filename, content, state);
166 
167         // 2. map file
168         MappedFile mf(filename);
169         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
170 
171         // check status
172         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
173         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
174 
175         // check size
176         struct stat stb = {0};
177         stat(filename.c_str(), &stb);
178         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
179             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
180 
181         // check map-mode
182         AssertEqual(MapMode::DEFAULT, mf.GetMode(), "MapMode::DEFAULT did not equal mf.GetMode() as expected.", state);
183 
184         // check offset
185         AssertEqual(mf.StartOffset(), 0u, "mf.StartOffset() did not equal 0u as expected.", state);
186 
187         // 3. read from mapped file
188         ReadFromMappedFile(content, mf, state);
189 
190         // 4. write to mapped file
191         std::string toWrite("Complete.");
192         WriteToMappedFile(toWrite, mf);
193         std::string res;
194         LoadStringFromFile(filename, res);
195         AssertEqual(res, "Complete.normal use.", "res did not equal \"Complete.normal use.\" as expected.", state);
196 
197         // 5. test default mapping and write to addr which excess End() but not across this memory page.
198         AssertLessThanOrEqual(mf.Size(), mf.PageSize(),
199             "mf.Size() was not less than or equal to mf.PageSize() as expected.", state);
200         char* trueEnd = mf.RegionEnd();
201         AssertGreaterThan(trueEnd, mf.Begin(), "trueEnd was not greater than mf.Begin() as expected.", state);
202         // write to mapped file
203         (*trueEnd) = 'E'; // It is allowed to write to this address which excess the End()
204 
205         AssertEqual((*trueEnd), 'E', "(*trueEnd) did not equal 'E' as expected.", state);
206 
207         std::string res1;
208         LoadStringFromFile(filename, res1);
209         AssertEqual(res1, "Complete.normal use.", "res1 did not equal \"Complete.normal use.\" as expected.", state);
210 
211         RemoveTestFile(filename);
212     }
213     BENCHMARK_LOGD("MappedFileTest testDefaultMapping001 end.");
214 }
215 
216 /*
217  * @tc.name: testNewSharedMappingDefaultSize001
218  * @tc.desc: Test mapping which will create a new file with default size.
219  */
BENCHMARK_F(BenchmarkMappedFileTest,testNewSharedMappingDefaultSize001)220 BENCHMARK_F(BenchmarkMappedFileTest, testNewSharedMappingDefaultSize001)(benchmark::State& state)
221 {
222     BENCHMARK_LOGD("MappedFileTest testNewSharedMappingDefaultSize001 start.");
223     while (state.KeepRunning()) {
224         // 1. Create a new file
225         std::string filename = "test_read_write_2.txt";
226         filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
227         RemoveTestFile(filename);
228 
229         // 2. map file
230         MappedFile mf(filename, MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT);
231         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
232 
233         // check if file is created
234         AssertTrue((FileExists(filename)), "FileExists(filename) did not equal true as expected.", state);
235 
236         // check status
237         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
238         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
239 
240         // check map-mode
241         AssertEqual((MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT), mf.GetMode(),
242             "(MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT) did not equal mf.GetMode() as expected.", state);
243 
244         // check default size
245         struct stat stb = {0};
246         if (stat(filename.c_str(), &stb) == 0) {
247             AssertEqual(stb.st_size, mf.PageSize(), "stb.st_size did not equal mf.PageSize() as expected.", state);
248         }
249         AssertEqual(mf.Size(), mf.PageSize(), "mf.Size() did not equal mf.PageSize() as expected.", state);
250 
251         // 3. write to mapped file
252         std::string toWrite("Write to newly created file.");
253         WriteToMappedFile(toWrite, mf);
254         std::string res;
255         LoadStringFromFile(filename, res);
256         AssertEqual(strcmp(res.c_str(), toWrite.c_str()), 0,
257             "The two strings, res.c_str() and toWrite.c_str(), did not have the same content as expected.", state);
258                                                     // use c_str() to compare conveniently.
259 
260         // 4. read from mapped file
261         std::string toRead("Waiting to be read.");
262         SaveStringToFile(filename, toRead, 0, true);
263         std::string readout;
264         for (char* cur = mf.Begin(); *cur != '\0'; cur++) {
265             readout.push_back(*cur);
266         }
267         AssertEqual(readout, toRead, "readout did not equal toRead as expected.", state);
268 
269         RemoveTestFile(filename);
270     }
271     BENCHMARK_LOGD("MappedFileTest testNewSharedMappingDefaultSize001 end.");
272 }
273 
274 /*
275  * @tc.name: testNewSharedMapping001
276  * @tc.desc: Test mapping which will create a new file with specified params.
277  */
BENCHMARK_F(BenchmarkMappedFileTest,testNewSharedMapping001)278 BENCHMARK_F(BenchmarkMappedFileTest, testNewSharedMapping001)(benchmark::State& state)
279 {
280     BENCHMARK_LOGD("MappedFileTest testNewSharedMapping001 start.");
281     while (state.KeepRunning()) {
282         std::string filename = "test_read_write_3.txt";
283         filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
284         RemoveTestFile(filename);
285 
286         // set params
287         // new mapping region will not guaranteed to be located at `hint`
288         char* hint = reinterpret_cast<char*>(0x80000); // 0x80000: hint(expected address).
289         off_t size = 1024;
290         off_t offset = 4 * 1024;
291 
292         // 1. map a non-existed file
293         MappedFile mf(filename, MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT, offset, size, hint);
294         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
295 
296         // check if file is created
297         AssertTrue((FileExists(filename)), "FileExists(filename) did not equal true as expected.", state);
298 
299         // check status
300         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
301         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
302 
303         // check specified size
304         struct stat stb = {0};
305         if (stat(filename.c_str(), &stb) == 0) {
306             // Exact file size should be offset + mapped size, contents will be zero-filled.
307             AssertEqual(stb.st_size, offset + size, "stb.st_size did not equal offset + size as expected.", state);
308         }
309         AssertEqual(mf.Size(), size, "mf.Size() did not equal size as expected.", state);
310 
311         // check specified offset
312         AssertEqual(mf.StartOffset(), offset, "mf.StartOffset() did not equal offset as expected.", state);
313 
314         // check hint
315         AssertTrue((mf.GetHint() == nullptr || mf.GetHint() == hint),
316             "(mf.GetHint() == nullptr || mf.GetHint() == hint) did not equal true as expected.", state);
317 
318         // 2. write to mapped file
319         std::string toWrite("Write to newly created file.");
320         WriteToMappedFile(toWrite, mf);
321         AssertTrue((StringExistsInFile(filename, toWrite)),
322             "StringExistsInFile(filename, toWrite) did not equal true as expected.", state);
323 
324         // 3. read from mapped file
325         std::string toRead("Waiting to be read.");
326         SaveStringToFile(filename, toRead, offset, true);
327         std::string readout;
328         for (char* cur = mf.Begin(); cur <= mf.End() && *cur != '\0'; cur++) {
329             readout.push_back(*cur);
330         }
331         AssertEqual(readout, toRead, "readout did not equal toRead as expected.", state);
332 
333         RemoveTestFile(filename);
334     }
335     BENCHMARK_LOGD("MappedFileTest testNewSharedMapping001 end.");
336 }
337 
338 /*
339  * @tc.name: testPrivateMapping001
340  * @tc.desc: Test mapping which will create a new file with specified params.
341  */
BENCHMARK_F(BenchmarkMappedFileTest,testPrivateMapping001)342 BENCHMARK_F(BenchmarkMappedFileTest, testPrivateMapping001)(benchmark::State& state)
343 {
344     BENCHMARK_LOGD("MappedFileTest testPrivateMapping001 start.");
345     while (state.KeepRunning()) {
346         // 1. create a new file
347         std::string filename = "test_read_write_4.txt";
348         std::string content = "Test for private use.";
349         CreateFile(filename, content, state);
350 
351         // 2. map file
352         MappedFile mf(filename, MapMode::DEFAULT | MapMode::PRIVATE);
353         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
354 
355         // 3. check status
356         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
357         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
358 
359         // 4. read from mapped file
360         ReadFromMappedFile(content, mf, state);
361 
362         // 5. write to mapped file
363         std::string toWrite("Complete.");
364         WriteToMappedFile(toWrite, mf);
365         std::string res;
366         LoadStringFromFile(filename, res);
367         AssertEqual(res, content, "res did not equal content as expected.", state);
368 
369         RemoveTestFile(filename);
370     }
371     BENCHMARK_LOGD("MappedFileTest testPrivateMapping001 end.");
372 }
373 
374 /*
375  * @tc.name: testSharedReadOnlyMapping001
376  * @tc.desc: Test mapping which will create a new file with specified params.
377  */
BENCHMARK_F(BenchmarkMappedFileTest,testSharedReadOnlyMapping001)378 BENCHMARK_F(BenchmarkMappedFileTest, testSharedReadOnlyMapping001)(benchmark::State& state)
379 {
380     BENCHMARK_LOGD("MappedFileTest testSharedReadOnlyMapping001 start.");
381     while (state.KeepRunning()) {
382         // 1. create a new file
383         std::string filename = "test_read_write_5.txt";
384         std::string content = "Test for readonly use.";
385         CreateFile(filename, content, state);
386 
387         // 2. map file
388         MappedFile mf(filename, MapMode::DEFAULT | MapMode::READ_ONLY);
389         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
390 
391         // 3. check status
392         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
393         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
394 
395         // 4. read from mapped file
396         ReadFromMappedFile(content, mf, state);
397         // !Note: write operation is not permitted, which will raise a signal 11.
398 
399         RemoveTestFile(filename);
400     }
401     BENCHMARK_LOGD("MappedFileTest testSharedReadOnlyMapping001 end.");
402 }
403 
404 /*
405  * @tc.name: testReMap001
406  * @tc.desc: Test remapping using `Unmap()` and `Map()`
407  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap001)408 BENCHMARK_F(BenchmarkMappedFileTest, testReMap001)(benchmark::State& state)
409 {
410     BENCHMARK_LOGD("MappedFileTest testReMap001 start.");
411     while (state.KeepRunning()) {
412         // 1. create a new file
413         std::string filename = "test_remap_1.txt";
414         std::string content = "Test for remapping use.";
415         CreateFile(filename, content, state);
416 
417         // 2. map file
418         MappedFile mf(filename);
419         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
420 
421         // 3. check status after mapping
422         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
423         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
424 
425         AssertEqual(mf.Unmap(), MAPPED_FILE_ERR_OK,
426             "mf.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
427 
428         // 4. check status after unmapping
429         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
430         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
431         AssertEqual(mf.Begin(), nullptr, "mf.Begin() did not equal nullptr as expected.", state);
432 
433         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
434         // 5. check status after remapping
435         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
436         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
437 
438         // 6. check default size
439         struct stat stb = {0};
440         stat(filename.c_str(), &stb);
441         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
442             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
443 
444         RemoveTestFile(filename);
445     }
446     BENCHMARK_LOGD("MappedFileTest testReMap001 end.");
447 }
448 
ChangeParamsWhenUnmapped(MappedFile & mf,const int sizeIncrement,std::string & filename,std::string & filename1,benchmark::State & state)449 static void ChangeParamsWhenUnmapped(MappedFile& mf, const int sizeIncrement, std::string& filename,
450                                      std::string& filename1, benchmark::State& state)
451 {
452     AssertTrue((mf.ChangeSize(mf.Size() + sizeIncrement)),
453         "mf.ChangeSize(mf.Size() + sizeIncrement) did not equal true as expected.", state);
454     AssertTrue((mf.ChangeSize(MappedFile::DEFAULT_LENGTH)),
455         "mf.ChangeSize(MappedFile::DEFAULT_LENGTH) did not equal true as expected.", state);
456     AssertTrue((mf.ChangeOffset(mf.PageSize())),
457         "mf.ChangeOffset(mf.PageSize()) did not equal true as expected.", state);
458     AssertTrue((mf.ChangeOffset(0)), "mf.ChangeOffset(0) did not equal true as expected.", state);
459     AssertTrue((mf.ChangePath(filename1)), "mf.ChangePath(filename1) did not equal true as expected.", state);
460     AssertTrue((mf.ChangePath(filename)), "mf.ChangePath(filename) did not equal true as expected.", state);
461     AssertTrue((mf.ChangeHint(reinterpret_cast<char*>(0x89000))),
462         "mf.ChangeHint(reinterpret_cast<char*>(0x89000)) did not equal true as expected.", state);
463     AssertTrue((mf.ChangeMode(MapMode::READ_ONLY)),
464         "mf.ChangeMode(MapMode::READ_ONLY) did not equal true as expected.", state);
465 }
466 
467 /*
468  * @tc.name: testReMap002
469  * @tc.desc: Test remapping via changing params.
470  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap002)471 BENCHMARK_F(BenchmarkMappedFileTest, testReMap002)(benchmark::State& state)
472 {
473     BENCHMARK_LOGD("MappedFileTest testReMap002 start.");
474     const int sizeIncrement = 1024;
475     while (state.KeepRunning()) {
476         // 1. create a new file
477         std::string filename = "test_remap.txt";
478         std::string content = "Test for default use.";
479         CreateFile(filename, content, state);
480 
481         std::string filename1 = "test_remap_1.txt";
482         std::string content1 = "Test for remapping use.";
483         CreateFile(filename1, content1, state);
484 
485         MappedFile mf(filename);
486 
487         // Change params when unmapped.
488         ChangeParamsWhenUnmapped(mf, sizeIncrement, filename, filename1, state);
489 
490         // 2. map file
491         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
492 
493         // 3. check status after mapping
494         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
495         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
496 
497         // 4. check size
498         struct stat stb = {0};
499         stat(filename.c_str(), &stb);
500         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
501             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
502 
503         // 5. read from Mapped File
504         ReadFromMappedFile(content, mf, state);
505 
506         // 6. change params
507         AssertTrue((mf.ChangePath(filename1)), "mf.ChangePath(filename1) did not equal true as expected.", state);
508         AssertTrue((mf.ChangeSize(MappedFile::DEFAULT_LENGTH)),
509             "mf.ChangeSize(MappedFile::DEFAULT_LENGTH) did not equal true as expected.", state);
510         AssertTrue((mf.ChangeHint(reinterpret_cast<char*>(0x80000))),
511             "mf.ChangeHint(reinterpret_cast<char*>(0x80000)) did not equal true as expected.", state);
512         AssertTrue((mf.ChangeMode(MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT)),
513             "mf.ChangeMode(MapMode::DEFAULT | MapMode::CREATE_IF_ABSENT) did not equal true as expected.", state);
514 
515         // 7. check status after changing
516         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
517         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
518 
519         // 8. remap file
520         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
521         // 9. check status after remapping
522         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
523         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
524 
525         // 10. check size
526         stat(filename1.c_str(), &stb);
527         AssertEqual(stb.st_size, mf.Size(), "stb.st_size == mf.Size() did not equal true as expected.", state);
528 
529         // 11. read from Mapped File
530         ReadFromMappedFile(content1, mf, state);
531 
532         RemoveTestFile(filename);
533         RemoveTestFile(filename1);
534     }
535     BENCHMARK_LOGD("MappedFileTest testReMap002 end.");
536 }
537 
538 /*
539  * @tc.name: testReMap003
540  * @tc.desc: Test remapping via Resize().
541  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap003)542 BENCHMARK_F(BenchmarkMappedFileTest, testReMap003)(benchmark::State& state)
543 {
544     BENCHMARK_LOGD("MappedFileTest testReMap003 start.");
545     while (state.KeepRunning()) {
546         // 1. create a new file
547         std::string filename = "test_remap.txt";
548         std::string content = "Test for default use.";
549         CreateFile(filename, content, state);
550 
551         std::string filename1 = "test_remap_1.txt";
552         std::string content1 = "Test for remapping use.";
553         CreateFile(filename1, content1, state);
554 
555         // 2. map file
556         MappedFile mf(filename);
557         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
558 
559         // 3. check status after mapping
560         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
561         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
562 
563         // 4. check size
564         struct stat stb = {0};
565         stat(filename.c_str(), &stb);
566         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
567             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
568 
569         // 5. read from Mapped File
570         ReadFromMappedFile(content, mf, state);
571 
572         // 6. change params
573         mf.ChangePath(filename1);
574         mf.ChangeSize(MappedFile::DEFAULT_LENGTH);
575 
576         // 7. check status after changing
577         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
578         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
579 
580         // 8. remap file
581         AssertEqual(mf.Resize(), MAPPED_FILE_ERR_OK,
582             "mf.Resize() did not equal MAPPED_FILE_ERR_OK as expected.", state);
583         // 9. check status after remapping
584         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
585         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
586 
587         // 10. check size
588         stat(filename1.c_str(), &stb);
589         AssertEqual(stb.st_size, mf.Size(), "stb.st_size == mf.Size() did not equal true as expected.", state);
590 
591         // 11. read from Mapped File
592         ReadFromMappedFile(content1, mf, state);
593 
594         RemoveTestFile(filename);
595         RemoveTestFile(filename1);
596     }
597     BENCHMARK_LOGD("MappedFileTest testReMap003 end.");
598 }
599 
600 /*
601  * @tc.name: testReMap004
602  * @tc.desc: Test remapping only to extend mapped region via Resize(off_t, bool).
603  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap004)604 BENCHMARK_F(BenchmarkMappedFileTest, testReMap004)(benchmark::State& state)
605 {
606     BENCHMARK_LOGD("MappedFileTest testReMap004 start.");
607     while (state.KeepRunning()) {
608         // 1. create a new file
609         std::string filename = "test_remap.txt";
610         std::string content = "Test for remapping use.";
611         CreateFile(filename, content, state);
612 
613         // 2. map file
614         MappedFile mf(filename);
615         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
616 
617         // 3. check status after mapping
618         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
619         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
620 
621         // 4. check size
622         struct stat stb = {0};
623         stat(filename.c_str(), &stb);
624         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
625             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
626 
627         // 5. read from Mapped File
628         char* cur = mf.Begin();
629         std::string readout;
630         for (; cur <= mf.End(); cur++) {
631             readout.push_back(*cur);
632         }
633         AssertEqual(readout, content, "readout did not equal content as expected.", state);
634 
635         // 6. Remap to extend region
636         const int newSize = 10;
637         AssertEqual(mf.Resize(mf.Size() + newSize), MAPPED_FILE_ERR_OK,
638             "mf.Resize(mf.Size() + newSize) did not equal MAPPED_FILE_ERR_OK as expected.", state);
639         // 7. check status after remapping
640         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
641         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
642 
643         // 8. check size after remapping
644         stat(filename.c_str(), &stb);
645         AssertLessThan(stb.st_size, mf.Size(), "stb.st_size < mf.Size() did not equal true as expected.", state);
646 
647         // 9. write to the extended region
648         *(cur) = 'E';
649         AssertEqual((*cur), 'E', "(*cur) did not equal 'E' as expected.", state);
650 
651         std::string res;
652         LoadStringFromFile(filename, res);
653         AssertEqual(res, content, "res did not equal content as expected.", state);
654                                 // is larger than substantial size of the file
655 
656         RemoveTestFile(filename);
657     }
658     BENCHMARK_LOGD("MappedFileTest testReMap004 end.");
659 }
660 
661 /*
662  * @tc.name: testReMap005
663  * @tc.desc: Test remapping to extend mapped region as well as substantial file size via Resize(off_t, bool).
664  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap005)665 BENCHMARK_F(BenchmarkMappedFileTest, testReMap005)(benchmark::State& state)
666 {
667     BENCHMARK_LOGD("MappedFileTest testReMap005 start.");
668     while (state.KeepRunning()) {
669         // 1. create a new file
670         std::string content = "Test for remapping use.";
671         std::string filename = "test_remap.txt";
672         CreateFile(filename, content, state);
673 
674         // 2. map file
675         MappedFile mf(filename);
676         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
677 
678         // 3. check status after mapping
679         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
680         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
681 
682         // 4. check size
683         struct stat stb = {0};
684         stat(filename.c_str(), &stb);
685         AssertTrue((stb.st_size == mf.Size() || mf.PageSize() == mf.Size()),
686             "stb.st_size == mf.Size() || mf.PageSize() == mf.Size() did not equal true as expected.", state);
687 
688         // 5. read from Mapped File
689         std::string readout;
690         char* cur = mf.Begin();
691         for (; cur <= mf.End(); cur++) {
692             readout.push_back(*cur);
693         }
694         AssertEqual(readout, content, "readout did not equal content as expected.", state);
695 
696         // 6. remap to extend region
697         const int newSize = 10;
698         AssertEqual(mf.Resize(mf.Size() + newSize, true), MAPPED_FILE_ERR_OK,
699             "mf.Resize(mf.Size() + newSize, true) did not equal MAPPED_FILE_ERR_OK as expected.", state);
700         // check status after remapping
701         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
702         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
703 
704         // 7. check size after remapping
705         stat(filename.c_str(), &stb);
706         AssertEqual(stb.st_size, mf.Size(), "stb.st_size == mf.Size() did not equal true as expected.", state);
707 
708         // 8. write to the extended region
709         *(cur) = 'E';
710         AssertEqual((*cur), 'E', "(*cur) did not equal 'E' as expected.", state);
711 
712         std::string res;
713         LoadStringFromFile(filename, res);
714         AssertEqual(strcmp(res.c_str(), content.append("E").c_str()), 0,
715             "The two strings, res.c_str() and content.append(\"E\").c_str(), \
716             did not have the same content as expected.", state);
717     }
718     BENCHMARK_LOGD("MappedFileTest testReMap005 end.");
719 }
720 
721 /*
722  * @tc.name: testReMap006
723  * @tc.desc: Test remapping to via Resize(off_t, bool).
724  */
BENCHMARK_F(BenchmarkMappedFileTest,testReMap006)725 BENCHMARK_F(BenchmarkMappedFileTest, testReMap006)(benchmark::State& state)
726 {
727     BENCHMARK_LOGD("MappedFileTest testReMap006 start.");
728     while (state.KeepRunning()) {
729         // 1. create a new file
730         std::string filename = "test_remap.txt";
731         std::string content = "Test for remapping use.";
732         CreateFile(filename, content, state);
733 
734         // 2. map file
735         off_t size = 20;
736         MappedFile mf(filename, MapMode::DEFAULT, 0, size);
737         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
738 
739         // 3. check status after mapping
740         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
741         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
742 
743         // 4. check size
744         AssertEqual(size, mf.Size(), "size == mf.Size() did not equal true as expected.", state);
745 
746         // 5. remap to extend region
747         AssertEqual(mf.Resize(MappedFile::DEFAULT_LENGTH, true), MAPPED_FILE_ERR_OK,
748             "mf.Resize(MappedFile::DEFAULT_LENGTH, true) did not equal MAPPED_FILE_ERR_OK as expected.", state);
749         off_t sizeDifference = 8;
750         off_t lessSize = mf.Size() - sizeDifference;
751         AssertEqual(mf.Resize(lessSize, true), MAPPED_FILE_ERR_OK,
752             "mf.Resize(lessSize, true) did not equal MAPPED_FILE_ERR_OK as expected.", state);
753         // check status after remapping
754         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
755         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
756 
757         // 6. check size after remapping
758         struct stat stb = {0};
759         stat(filename.c_str(), &stb);
760         AssertEqual(lessSize, mf.Size(), "lessSize did not equal mf.Size() as expected.", state);
761     }
762     BENCHMARK_LOGD("MappedFileTest testReMap006 end.");
763 }
764 
KeepAPageAndReachBottom(off_t & endOff,const off_t orig,MappedFile & mf,benchmark::State & state)765 void KeepAPageAndReachBottom(off_t& endOff, const off_t orig, MappedFile& mf, benchmark::State& state)
766 {
767     AssertUnequal(orig, CONSTANT_ZERO, "The divisor cannot be 0", state);
768     if (orig != CONSTANT_ZERO) {
769         // keep turnNext within a page
770         for (unsigned int cnt = 2; cnt < (MappedFile::PageSize() / orig); cnt++) {
771             // 2: start from 2 to take the first, TunrNext() calling in consideration.
772             endOff = mf.EndOffset();
773             AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
774                 "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
775             AssertEqual(mf.StartOffset(), endOff + 1, "mf.StartOffset() did not equal endOff + 1 as expected.", state);
776             AssertEqual(mf.Size(), orig, "mf.Size() did not equal orig as expected.", state);
777         }
778         PrintStatus(mf);
779     }
780 
781     // this turn will reach the bottom of a page
782     endOff = mf.EndOffset();
783     char* rEnd = mf.RegionEnd();
784     char* end = mf.End();
785     AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
786         "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
787     AssertEqual(mf.StartOffset(), endOff + 1, "mf.StartOffset() did not equal endOff + 1 as expected.", state);
788     AssertEqual(mf.Size(), static_cast<off_t>(rEnd - end),
789         "mf.Size() did not equal static_cast<off_t>(rEnd - end) as expected.", state);
790     PrintStatus(mf);
791 }
792 
Remapping(MappedFile & mf,off_t & endOff,off_t & curSize,benchmark::State & state)793 static void Remapping(MappedFile& mf, off_t& endOff, off_t& curSize, benchmark::State& state)
794 {
795     // 7. this turn will trigger a remapping
796     endOff = mf.EndOffset();
797     AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
798         "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
799     AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
800     AssertEqual(mf.StartOffset(), endOff + 1, "mf.StartOffset() did not equal endOff + 1 as expected.", state);
801     AssertEqual(mf.Size(), curSize, "mf.Size() did not equal curSize as expected.", state);
802     AssertEqual(mf.RegionStart(), mf.Begin(), "mf.RegionStart() did not equal mf.Begin() as expected.", state);
803     AssertEqual(static_cast<off_t>(mf.RegionEnd() - mf.RegionStart()) + 1LL, mf.PageSize(),
804         "static_cast<off_t>(mf.RegionEnd() - mf.RegionStart()) + 1LL did not equal mf.PageSize().", state);
805     PrintStatus(mf);
806 }
807 
808 /*
809  * @tc.name: testTurnNext001
810  * @tc.desc: Test TurnNext() when `IsMapped()`.
811  */
BENCHMARK_F(BenchmarkMappedFileTest,testTurnNext001)812 BENCHMARK_F(BenchmarkMappedFileTest, testTurnNext001)(benchmark::State& state)
813 {
814     BENCHMARK_LOGD("MappedFileTest testTurnNext001 start.");
815     while (state.KeepRunning()) {
816         // 1. create a new file
817         std::string filename = "test_remap.txt";
818         std::string content = "Test for remapping use.";
819         CreateFile(filename, content, state);
820 
821         struct stat stb = {0};
822         AssertEqual(stat(filename.c_str(), &stb), 0,
823             "stat(filename.c_str(), &stb) did not equal 0 as expected.", state);
824         off_t orig = stb.st_size; // 23 bytes
825 
826         // 2. extend its size
827         int fd = open(filename.c_str(), O_RDWR | O_CLOEXEC);
828         AssertUnequal(fd, -1, "fd was not different from -1 as expected.", state);
829         AssertEqual(ftruncate(fd, MappedFile::PageSize() + MappedFile::PageSize() / 100LL), 0,
830             "ftruncate(fd, MappedFile::PageSize() + MappedFile::PageSize() / 100LL) did not equal 0.", state);
831 
832         // 3. map file
833         MappedFile mf(filename, MapMode::DEFAULT, 0, orig);
834         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
835 
836         // 4. check status after mapping
837         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
838         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
839 
840         // 5. turn next mapped region with the same size as the file's initial size.
841         AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
842             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
843         char* cur = mf.Begin();
844         *cur = 'N';
845 
846         std::string res;
847         LoadStringFromFile(filename, res);
848         AssertEqual(strcmp(res.c_str(), content.append("N").c_str()), 0,
849             "The two strings, res.c_str() and content.append(\"N\").c_str(), did not have the same content.", state);
850 
851         off_t endOff;
852         // 6. keep turnNext within a page,and reach the bottom of a page
853         KeepAPageAndReachBottom(endOff, orig, mf, state);
854 
855         // 7. this turn will trigger a remapping
856         off_t curSize = mf.Size();
857         Remapping(mf, endOff, curSize, state);
858 
859         // 8. keep turnNext within a page
860         for (off_t cnt = 1; cnt < (MappedFile::PageSize() / 100LL / curSize); cnt++) {
861             endOff = mf.EndOffset();
862             AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
863             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
864             AssertEqual(mf.StartOffset(), endOff + 1, "mf.StartOffset() did not equal endOff + 1 as expected.", state);
865             AssertEqual(mf.Size(), curSize, "mf.Size() did not equal curSize as expected.", state);
866         }
867 
868         // 9. this turn will fail since no place remained.
869         AssertUnequal(mf.TurnNext(), MAPPED_FILE_ERR_OK,
870             "mf.TurnNext() was not different from MAPPED_FILE_ERR_OK as expected.", state);
871 
872         RemoveTestFile(filename);
873     }
874     BENCHMARK_LOGD("MappedFileTest testTurnNext001 end.");
875 }
876 
877 /*
878  * @tc.name: testTurnNext002
879  * @tc.desc: Test TurnNext() when `!IsMapped()`.
880  */
BENCHMARK_F(BenchmarkMappedFileTest,testTurnNext002)881 BENCHMARK_F(BenchmarkMappedFileTest, testTurnNext002)(benchmark::State& state)
882 {
883     BENCHMARK_LOGD("MappedFileTest testTurnNext002 start.");
884     while (state.KeepRunning()) {
885         // 1. create a new file
886         std::string filename = "test_remap.txt";
887         std::string content = "Test for remapping use.";
888         CreateFile(filename, content, state);
889 
890         // 2. map file
891         MappedFile mf(filename);
892         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
893         off_t curSize = mf.Size();
894         off_t curOff = mf.StartOffset();
895 
896         // 3. check status after mapping
897         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
898         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
899         // 4. recommand to unmap first before other operations on the file.
900         AssertEqual(mf.Unmap(), MAPPED_FILE_ERR_OK,
901             "mf.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
902         // 5. enlarge file size to make it possible to `turnNext()`.
903         AssertEqual(ftruncate(mf.GetFd(), MappedFile::PageSize() + MappedFile::PageSize() / 100LL), 0,
904             "ftruncate(mf.GetFd(), MappedFile::PageSize() + MappedFile::PageSize() / 100LL) did not equal 0.", state);
905         // 6. turn next page of `PageSize()` and keep the same `size_`
906         AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
907             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
908         AssertEqual(mf.Size(), curSize, "mf.Size() did not equal curSize as expected.", state);
909         AssertEqual(static_cast<off_t>(mf.StartOffset()), curOff + mf.PageSize(),
910             "static_cast<off_t>(mf.StartOffset()) did not equal curOff + mf.PageSize() as expected.", state);
911 
912         RemoveTestFile(filename);
913     }
914     BENCHMARK_LOGD("MappedFileTest testTurnNext002 end.");
915 }
916 
917 /*
918  * @tc.name: testTurnNext003
919  * @tc.desc: Test TurnNext() (using internal fd to `ftruncate()`).
920  */
BENCHMARK_F(BenchmarkMappedFileTest,testTurnNext003)921 BENCHMARK_F(BenchmarkMappedFileTest, testTurnNext003)(benchmark::State& state)
922 {
923     BENCHMARK_LOGD("MappedFileTest testTurnNext003 start.");
924     while (state.KeepRunning()) {
925         // 1. create a new file
926         std::string filename = "test_remap.txt";
927         std::string content = "Test for remapping use.";
928         CreateFile(filename, content, state);
929 
930         // 2. map file
931         MappedFile mf(filename);
932         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
933 
934         // 3. check status after mapping
935         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
936         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
937 
938         // 4. recommand to unmap first before other operations on the file.
939         AssertEqual(mf.Unmap(), MAPPED_FILE_ERR_OK,
940             "mf.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
941         // 5. enlarge file size to make it possible to `turnNext()`.
942         AssertEqual(ftruncate(mf.GetFd(), MappedFile::PageSize() + MappedFile::PageSize() / 100LL), 0,
943             "ftruncate(mf.GetFd(), MappedFile::PageSize() + MappedFile::PageSize() / 100LL) did not equal 0.", state);
944 
945         // 6. remap
946         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
947 
948         // 7. turn next mapped region with the same size as the file's initial size.
949         AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
950             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
951         char* cur = mf.Begin();
952         *cur = 'N';
953 
954         std::string res;
955         LoadStringFromFile(filename, res);
956         AssertEqual(strcmp(res.c_str(), content.append("N").c_str()), 0,
957             "The two strings, res.c_str() and content.append(\"N\").c_str(), did not have the same content.", state);
958 
959         RemoveTestFile(filename);
960     }
961     BENCHMARK_LOGD("MappedFileTest testTurnNext003 end.");
962 }
963 
964 /*
965  * @tc.name: testTurnNext004
966  * @tc.desc: Test TurnNext() failed.
967  */
BENCHMARK_F(BenchmarkMappedFileTest,testTurnNext004)968 BENCHMARK_F(BenchmarkMappedFileTest, testTurnNext004)(benchmark::State& state)
969 {
970     BENCHMARK_LOGD("MappedFileTest testTurnNext004 start.");
971     while (state.KeepRunning()) {
972         // 1. create a new file
973         std::string filename = "test_remap.txt";
974         std::string content = "Test for remapping use.";
975         CreateFile(filename, content, state);
976 
977         // 2. map file
978         MappedFile mf(filename);
979         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
980 
981         // 3. check status after mapping
982         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
983         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
984 
985         // 4. turn next mapped region with the same size as the file's initial size.
986         AssertEqual(mf.TurnNext(), ERR_INVALID_OPERATION,
987             "mf.TurnNext() did not equal ERR_INVALID_OPERATION as expected.", state);
988 
989         RemoveTestFile(filename);
990     }
991     BENCHMARK_LOGD("MappedFileTest testTurnNext004 end.");
992 }
993 
994 /*
995  * @tc.name: testTurnNext005
996  * @tc.desc: Test TurnNext() with file size less than one page.
997  */
BENCHMARK_F(BenchmarkMappedFileTest,testTurnNext005)998 BENCHMARK_F(BenchmarkMappedFileTest, testTurnNext005)(benchmark::State& state)
999 {
1000     BENCHMARK_LOGD("MappedFileTest testTurnNext005 start.");
1001     while (state.KeepRunning()) {
1002         // 1. create a new file
1003         std::string filename = "test_remap.txt";
1004         std::string content = "Test for remapping use.00";
1005         CreateFile(filename, content, state);
1006 
1007         struct stat stb = {0};
1008         AssertEqual(stat(filename.c_str(), &stb), 0,
1009             "stat(filename.c_str(), &stb) did not equal 0 as expected.", state);
1010         off_t orig = stb.st_size; // 25 bytes
1011 
1012         // 2. extend its size
1013         int fd = open(filename.c_str(), O_RDWR | O_CLOEXEC);
1014         AssertUnequal(fd, -1, "fd was not different from -1 as expected.", state);
1015         const int newSize = 10;
1016         AssertEqual(ftruncate(fd, MappedFile::PageSize() + newSize), 0,
1017             "ftruncate(fd, MappedFile::PageSize() + newSize) did not equal 0 as expected.", state);
1018 
1019         // 3. map file
1020         MappedFile mf(filename, MapMode::DEFAULT, 0, orig);
1021         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1022 
1023         // 4. check status after mapping
1024         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1025         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1026 
1027         // 5. turn next mapped region with the same size as the file's initial size.
1028         AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
1029             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1030 
1031         off_t endOff;
1032         // 6. keep turnNext within a page,and reach the bottom of a page
1033         KeepAPageAndReachBottom(endOff, orig, mf, state);
1034 
1035         // 7. this turn will trigger a remapping
1036         endOff = mf.EndOffset();
1037         AssertEqual(mf.TurnNext(), MAPPED_FILE_ERR_OK,
1038             "mf.TurnNext() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1039         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1040         AssertEqual(mf.StartOffset(), endOff + 1, "mf.StartOffset() did not equal endOff + 1 as expected.", state);
1041         const int expectedSize = 10;
1042         AssertEqual(mf.Size(), expectedSize, "mf.Size() did not equal expectedSize as expected.", state);
1043         AssertEqual(mf.RegionStart(), mf.Begin(), "mf.RegionStart() did not equal mf.Begin() as expected.", state);
1044         AssertEqual(static_cast<off_t>(mf.RegionEnd() - mf.RegionStart()) + 1LL, mf.PageSize(),
1045             "static_cast<off_t>(mf.RegionEnd() - mf.RegionStart()) + 1LL did not equal mf.PageSize().", state);
1046         PrintStatus(mf);
1047     }
1048     BENCHMARK_LOGD("MappedFileTest testTurnNext005 end.");
1049 }
1050 
1051 /*
1052  * @tc.name: testInvalidMap001
1053  * @tc.desc: Test file mapping with invalid offset.
1054  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap001)1055 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap001)(benchmark::State& state)
1056 {
1057     BENCHMARK_LOGD("MappedFileTest testInvalidMap001 start.");
1058     while (state.KeepRunning()) {
1059         // 1. create a new file
1060         std::string filename = "test_invalid_1.txt";
1061         std::string content = "Test for invalid use.";
1062         CreateFile(filename, content, state);
1063 
1064         // 2. map file
1065         off_t offset = 100; // Specify offset that is not multiple of page-size.
1066         MappedFile mf(filename, MapMode::DEFAULT, offset);
1067         AssertUnequal(mf.Map(), MAPPED_FILE_ERR_OK,
1068             "mf.Map() was not different from MAPPED_FILE_ERR_OK as expected.", state);
1069 
1070         MappedFile mf1(filename, MapMode::DEFAULT, -1);
1071         AssertUnequal(mf1.Map(), MAPPED_FILE_ERR_OK,
1072             "mf1.Map() was not different from MAPPED_FILE_ERR_OK as expected.", state);
1073 
1074         // 3. check status
1075         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1076         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1077         AssertFalse((mf1.IsMapped()), "mf1.IsMapped() did not equal false as expected.", state);
1078         AssertFalse((mf1.IsNormed()), "mf1.IsNormed() did not equal false as expected.", state);
1079 
1080         RemoveTestFile(filename);
1081     }
1082     BENCHMARK_LOGD("MappedFileTest testInvalidMap001 end.");
1083 }
1084 
1085 /*
1086  * @tc.name: testInvalidMap002
1087  * @tc.desc: Test file mapping with invalid offset excessing the substantial size of the file.
1088  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap002)1089 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap002)(benchmark::State& state)
1090 {
1091     BENCHMARK_LOGD("MappedFileTest testInvalidMap002 start.");
1092     while (state.KeepRunning()) {
1093         // 1. create a new file
1094         std::string filename = "test_invalid_2.txt";
1095         std::string content = "Test for invalid use.";
1096         CreateFile(filename, content, state);
1097 
1098         // 2. map file
1099         off_t offset = 4 * 1024; // Specify offset excessing the substantial size of the file.
1100         MappedFile mf(filename, MapMode::DEFAULT, offset);
1101         AssertUnequal(mf.Map(), MAPPED_FILE_ERR_OK,
1102             "mf.Map() was not different from MAPPED_FILE_ERR_OK as expected.", state);
1103 
1104         // 3. check status
1105         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1106         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1107 
1108         RemoveTestFile(filename);
1109     }
1110     BENCHMARK_LOGD("MappedFileTest testInvalidMap002 end.");
1111 }
1112 
1113 /*
1114  * @tc.name: testInvalidMap003
1115  * @tc.desc: Test mapping non-existed file without setting CREAT_IF_ABSENT.
1116  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap003)1117 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap003)(benchmark::State& state)
1118 {
1119     BENCHMARK_LOGD("MappedFileTest testInvalidMap003 start.");
1120     while (state.KeepRunning()) {
1121         // 1. create a new file
1122         std::string filename = "test_invalid_3.txt";
1123         filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
1124         RemoveTestFile(filename);
1125 
1126         // 2. map file
1127         MappedFile mf(filename);
1128         AssertUnequal(mf.Map(), MAPPED_FILE_ERR_OK,
1129             "mf.Map() was not different from MAPPED_FILE_ERR_OK as expected.", state);
1130 
1131         // 3. check status
1132         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1133         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1134 
1135         RemoveTestFile(filename);
1136     }
1137     BENCHMARK_LOGD("MappedFileTest testInvalidMap003 end.");
1138 }
1139 
1140 /*
1141  * @tc.name: testInvalidMap004
1142  * @tc.desc: Test mapping with invalid size.
1143  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap004)1144 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap004)(benchmark::State& state)
1145 {
1146     BENCHMARK_LOGD("MappedFileTest testInvalidMap004 start.");
1147     while (state.KeepRunning()) {
1148         // 1. create a new file
1149         std::string filename = "test_invalid_4.txt";
1150         std::string content = "Test for invalid use.";
1151         CreateFile(filename, content, state);
1152 
1153         // 2. map file
1154         MappedFile mf(filename, MapMode::DEFAULT, 0, -2); // -2: less than DEFAULT_LENGTH(-1)
1155         AssertEqual(mf.Map(), ERR_INVALID_VALUE, "mf.Map() did not equal ERR_INVALID_VALUE as expected.", state);
1156 
1157         // 3. map again with another invalid param.
1158         MappedFile mf1(filename, MapMode::DEFAULT, 0, 0);
1159         AssertEqual(mf1.Map(), ERR_INVALID_VALUE, "mf1.Map() did not equal ERR_INVALID_VALUE as expected.", state);
1160 
1161         // 3. check status
1162         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1163         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1164         AssertFalse((mf1.IsMapped()), "mf1.IsMapped() did not equal false as expected.", state);
1165         AssertFalse((mf1.IsNormed()), "mf1.IsNormed() did not equal false as expected.", state);
1166 
1167         RemoveTestFile(filename);
1168     }
1169     BENCHMARK_LOGD("MappedFileTest testInvalidMap004 end.");
1170 }
1171 
1172 /*
1173  * @tc.name: testInvalidMap005
1174  * @tc.desc: Test mapping an already mapped file.
1175  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap005)1176 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap005)(benchmark::State& state)
1177 {
1178     BENCHMARK_LOGD("MappedFileTest testInvalidMap005 start.");
1179     while (state.KeepRunning()) {
1180         // 1. create a new file
1181         std::string filename = "test_invalid_6.txt";
1182         std::string content = "Test for invalid use.";
1183         CreateFile(filename, content, state);
1184 
1185         // 2. map file
1186         MappedFile mf(filename);
1187         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1188         AssertEqual(mf.Map(), ERR_INVALID_OPERATION,
1189             "mf.Map() did not equal ERR_INVALID_OPERATION as expected.", state);
1190 
1191         // 3. check status
1192         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1193         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1194 
1195         RemoveTestFile(filename);
1196     }
1197     BENCHMARK_LOGD("MappedFileTest testInvalidMap005 end.");
1198 }
1199 
1200 /*
1201  * @tc.name: testInvalidMap006
1202  * @tc.desc: Test resize with invalid params.
1203  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap006)1204 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap006)(benchmark::State& state)
1205 {
1206     BENCHMARK_LOGD("MappedFileTest testInvalidMap006 start.");
1207     while (state.KeepRunning()) {
1208         // 1. create a new file
1209         std::string filename = "test_invalid_7.txt";
1210         std::string content = "Test for invalid use.";
1211         CreateFile(filename, content, state);
1212 
1213 
1214         // 2. map file
1215         MappedFile mf(filename);
1216         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1217 
1218         // 3. check status
1219         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1220         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1221 
1222         // 4. resize
1223         const int newSize1 = 0;
1224         AssertEqual(mf.Resize(newSize1), ERR_INVALID_OPERATION,
1225             "mf.Resize(newSize1) did not equal ERR_INVALID_OPERATION as expected.", state);
1226         const int newSize2 = -2;
1227         AssertEqual(mf.Resize(newSize2), ERR_INVALID_OPERATION,
1228             "mf.Resize(newSize2) did not equal ERR_INVALID_OPERATION as expected.", state);
1229         AssertEqual(mf.Resize(mf.Size()), ERR_INVALID_OPERATION,
1230             "mf.Resize(mf.Size()) did not equal ERR_INVALID_OPERATION as expected.", state);
1231 
1232         // 5. Unmap first then resize.
1233         AssertEqual(mf.Unmap(), MAPPED_FILE_ERR_OK,
1234             "mf.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1235         const int newSize3 = 8;
1236         AssertEqual(mf.Resize(mf.Size() + newSize3), ERR_INVALID_OPERATION,
1237             "mf.Resize(mf.Size() + newSize3) did not equal ERR_INVALID_OPERATION as expected.", state);
1238 
1239         RemoveTestFile(filename);
1240     }
1241     BENCHMARK_LOGD("MappedFileTest testInvalidMap006 end.");
1242 }
1243 
1244 /*
1245  * @tc.name: testInvalidMap007
1246  * @tc.desc: Test resize with no param changed.
1247  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap007)1248 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap007)(benchmark::State& state)
1249 {
1250     BENCHMARK_LOGD("MappedFileTest testInvalidMap007 start.");
1251     while (state.KeepRunning()) {
1252         // 1. create a new file
1253         std::string filename = "test_invalid_8.txt";
1254         std::string content = "Test for invalid use.";
1255         CreateFile(filename, content, state);
1256 
1257 
1258         // 2. map file
1259         MappedFile mf(filename);
1260         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1261 
1262         // 3. check status
1263         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1264         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1265 
1266         // 4. resize
1267         AssertEqual(mf.Resize(), ERR_INVALID_OPERATION,
1268             "mf.Resize() did not equal ERR_INVALID_OPERATION as expected.", state);
1269 
1270         RemoveTestFile(filename);
1271     }
1272     BENCHMARK_LOGD("MappedFileTest testInvalidMap007 end.");
1273 }
1274 
1275 /*
1276  * @tc.name: testInvalidMap008
1277  * @tc.desc: Test TurnNext() with params changed.
1278  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap008)1279 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap008)(benchmark::State& state)
1280 {
1281     BENCHMARK_LOGD("MappedFileTest testInvalidMap008 start.");
1282     while (state.KeepRunning()) {
1283         // 1. create a new file
1284         std::string filename = "test_invalid_9.txt";
1285         std::string content = "Test for invalid use.";
1286         CreateFile(filename, content, state);
1287 
1288 
1289         // 2. map file
1290         MappedFile mf(filename);
1291         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1292 
1293         // 3. check status
1294         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1295         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1296 
1297         // 5. Change params
1298         AssertTrue((mf.ChangeSize(mf.Size() + 1)),
1299             "mf.ChangeSize(mf.Size() + 1) did not equal true as expected.", state);
1300 
1301         // 6. check status
1302         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1303         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1304 
1305         // 4. turn next.
1306         AssertEqual(mf.TurnNext(), ERR_INVALID_OPERATION,
1307             "mf.TurnNext() did not equal ERR_INVALID_OPERATION as expected.", state);
1308 
1309         RemoveTestFile(filename);
1310     }
1311     BENCHMARK_LOGD("MappedFileTest testInvalidMap008 end.");
1312 }
1313 
1314 /*
1315  * @tc.name: testInvalidMap009
1316  * @tc.desc: Test ChangeXX() with invalid params.
1317  */
BENCHMARK_F(BenchmarkMappedFileTest,testInvalidMap009)1318 BENCHMARK_F(BenchmarkMappedFileTest, testInvalidMap009)(benchmark::State& state)
1319 {
1320     BENCHMARK_LOGD("MappedFileTest testInvalidMap009 start.");
1321     while (state.KeepRunning()) {
1322         // 1. create a new file
1323         std::string filename = "test_invalid_10.txt";
1324         std::string content = "Test for invalid use.";
1325         CreateFile(filename, content, state);
1326 
1327 
1328         // 2. create MappedFile
1329         MappedFile mf(filename);
1330 
1331         // 3. map file
1332         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1333 
1334         // 4. check status
1335         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1336         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1337 
1338         // 5. Change params
1339         AssertFalse((mf.ChangeOffset(mf.StartOffset())),
1340             "mf.ChangeOffset(mf.StartOffset()) did not equal false as expected.", state);
1341         AssertFalse((mf.ChangeSize(mf.Size())), "mf.ChangeSize(mf.Size()) did not equal false as expected.", state);
1342         AssertFalse((mf.ChangeHint(mf.GetHint())),
1343             "mf.ChangeHint(mf.GetHint()) did not equal false as expected.", state);
1344         AssertFalse((mf.ChangeMode(mf.GetMode())),
1345             "mf.ChangeMode(mf.GetMode()) did not equal false as expected.", state);
1346         AssertFalse((mf.ChangePath(mf.GetPath())),
1347             "mf.ChangePath(mf.GetPath()) did not equal false as expected.", state);
1348 
1349         RemoveTestFile(filename);
1350     }
1351     BENCHMARK_LOGD("MappedFileTest testInvalidMap009 end.");
1352 }
1353 
1354 /*
1355  * @tc.name: testAutoAdjustedMode001
1356  * @tc.desc: Test mapping file with invalid mapping mode, but can be auto adjusted.
1357  */
BENCHMARK_F(BenchmarkMappedFileTest,testAutoAdjustedMode001)1358 BENCHMARK_F(BenchmarkMappedFileTest, testAutoAdjustedMode001)(benchmark::State& state)
1359 {
1360     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedMode001 start.");
1361     while (state.KeepRunning()) {
1362         // 1. create a new file
1363         std::string filename = "test_adjmod_1.txt";
1364         std::string content = "Test for auto adj use.";
1365         CreateFile(filename, content, state);
1366 
1367 
1368         // 2. map file
1369         const int mapMode1 = 1;
1370         const int mapMode2 = 16;
1371         MapMode mode = static_cast<MapMode>(mapMode1) | static_cast<MapMode>(mapMode2) |
1372                     MapMode::PRIVATE | MapMode::READ_ONLY; // bits out of the scope will be ignored.
1373         MappedFile mf(filename, mode);
1374         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1375 
1376         // 3. check status
1377         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1378         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1379 
1380         // 4. check map-mode
1381         AssertEqual((MapMode::PRIVATE | MapMode::READ_ONLY), mf.GetMode(),
1382             "MapMode::PRIVATE | MapMode::READ_ONLY did not equal mf.GetMode() as expected.", state);
1383 
1384         RemoveTestFile(filename);
1385     }
1386     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedMode001 end.");
1387 }
1388 
1389 /*
1390  * @tc.name: testAutoAdjustedSize001
1391  * @tc.desc: Test file mapping with size excessing the last page of the file.
1392  */
BENCHMARK_F(BenchmarkMappedFileTest,testAutoAdjustedSize001)1393 BENCHMARK_F(BenchmarkMappedFileTest, testAutoAdjustedSize001)(benchmark::State& state)
1394 {
1395     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedSize001 start.");
1396     while (state.KeepRunning()) {
1397         // 1. create a new file
1398         std::string filename = "test_adjsize_1.txt";
1399         std::string content = "Test for auto adj use.";
1400         CreateFile(filename, content, state);
1401 
1402 
1403         // 2. map file
1404         off_t size = 5 * 1024; // Specified size excessing the last page of the file.
1405         MappedFile mf(filename, MapMode::DEFAULT, 0, size);
1406         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1407 
1408         // 3. check status
1409         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1410         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1411 
1412         // 4. check size
1413         struct stat stb = {0};
1414         stat(filename.c_str(), &stb);
1415         off_t max = (stb.st_size / mf.PageSize() + 1LL) * mf.PageSize() - 0LL;
1416         AssertEqual(mf.Size(), max, "mf.Size() did not equal max as expected.", state);
1417 
1418         RemoveTestFile(filename);
1419     }
1420     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedSize001 end.");
1421 }
1422 
1423 /*
1424  * @tc.name: testAutoAdjustedSize002
1425  * @tc.desc: Test file mapping with size excessing the last page of the file.
1426  */
BENCHMARK_F(BenchmarkMappedFileTest,testAutoAdjustedSize002)1427 BENCHMARK_F(BenchmarkMappedFileTest, testAutoAdjustedSize002)(benchmark::State& state)
1428 {
1429     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedSize002 start.");
1430     while (state.KeepRunning()) {
1431         // 1. create a new file
1432         std::string filename = "test_adjsize_2.txt";
1433         std::string content = "Test for auto adj use.";
1434         CreateFile(filename, content, state);
1435 
1436 
1437         // 2. Extend size manually
1438         int fd = open(filename.c_str(), O_RDWR | O_CLOEXEC);
1439         if (fd != -1) {
1440             const int newSize = 7 * 1024;
1441             ftruncate(fd, newSize);
1442 
1443             // 3. map file
1444             off_t offset = 4 * 1024;
1445             off_t size = 5 * 1024; // Specified size excessing the last page of the file.
1446             MappedFile mf(filename, MapMode::DEFAULT, offset, size);
1447             AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1448 
1449             // 4. check status
1450             AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1451             AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1452 
1453             // 5. check size
1454             struct stat stb = {0};
1455             stat(filename.c_str(), &stb);
1456             off_t max = (stb.st_size / mf.PageSize() + 1LL) * mf.PageSize() - offset;
1457             AssertEqual(mf.Size(), max, "mf.Size() did not equal max as expected.", state);
1458 
1459             close(fd);
1460         }
1461 
1462         RemoveTestFile(filename);
1463     }
1464     BENCHMARK_LOGD("MappedFileTest testAutoAdjustedSize002 end.");
1465 }
1466 
1467 /*
1468  * @tc.name: testMoveMappedFile001
1469  * @tc.desc: Test move constructor.
1470  */
BENCHMARK_F(BenchmarkMappedFileTest,testMoveMappedFile001)1471 BENCHMARK_F(BenchmarkMappedFileTest, testMoveMappedFile001)(benchmark::State& state)
1472 {
1473     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile001 start.");
1474     while (state.KeepRunning()) {
1475         // 1. create a new file
1476         std::string filename = "test_move_1.txt";
1477         std::string content = "Test for move use.";
1478         CreateFile(filename, content, state);
1479 
1480         // 2. map file
1481         MappedFile mf(filename);
1482         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1483 
1484         off_t size = mf.Size();
1485         off_t offset = mf.StartOffset();
1486         char* data = mf.Begin();
1487         MapMode mode = mf.GetMode();
1488         const char* hint = mf.GetHint();
1489 
1490         // 3. move to a new object
1491         MappedFile mfNew(std::move(mf));
1492 
1493         // 4. check status and params after move
1494         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1495         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1496 
1497         AssertEqual(mf.Begin(), nullptr, "mf.Begin() did not equal nullptr as expected.", state);
1498         AssertEqual(mf.Size(), MappedFile::DEFAULT_LENGTH,
1499             "mf.Size() did not equal MappedFile::DEFAULT_LENGTH as expected.", state);
1500         AssertEqual(mf.StartOffset(), 0, "mf.StartOffset() did not equal 0 as expected.", state);
1501         AssertEqual(mf.GetMode(), MapMode::DEFAULT,
1502             "mf.GetMode() did not equal MapMode::DEFAULT as expected.", state);
1503         AssertEqual(mf.GetHint(), nullptr, "mf.GetHint() did not equal nullptr as expected.", state);
1504         AssertEqual(mf.GetPath(), "", "mf.GetPath() did not equal "" as expected.", state);
1505 
1506         AssertTrue((mfNew.IsNormed()), "mfNew.IsNormed() did not equal true as expected.", state);
1507         AssertTrue((mfNew.IsMapped()), "mfNew.IsMapped() did not equal true as expected.", state);
1508         AssertEqual(mfNew.Begin(), data, "mfNew.Begin() did not equal data as expected.", state);
1509         AssertEqual(mfNew.Size(), size, "mfNew.Size() did not equal size as expected.", state);
1510         AssertEqual(mfNew.StartOffset(), offset, "mfNew.StartOffset() did not equal offset as expected.", state);
1511         AssertEqual(mfNew.GetMode(), mode, "mfNew.GetMode() did not equal mode as expected.", state);
1512         AssertEqual(mfNew.GetHint(), hint, "mfNew.GetHint() did not equal hint as expected.", state);
1513         AssertEqual(mfNew.GetPath(), filename, "mfNew.GetPath() did not equal filename as expected.", state);
1514 
1515         // 5. read from mapped file
1516         ReadFromMappedFile(content, mfNew, state);
1517 
1518         // 6. write to mapped file
1519         std::string toWrite("Complete.");
1520         WriteToMappedFile(toWrite, mfNew);
1521         std::string res;
1522         LoadStringFromFile(filename, res);
1523         AssertEqual(res, "Complete.move use.", "res did not equal \"Complete.move use.\" as expected.", state);
1524 
1525         RemoveTestFile(filename);
1526     }
1527     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile001 end.");
1528 }
1529 
1530 /*
1531  * @tc.name: testMoveMappedFile002
1532  * @tc.desc: Test move constructor with ummapped region.
1533  */
BENCHMARK_F(BenchmarkMappedFileTest,testMoveMappedFile002)1534 BENCHMARK_F(BenchmarkMappedFileTest, testMoveMappedFile002)(benchmark::State& state)
1535 {
1536     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile002 start.");
1537     while (state.KeepRunning()) {
1538         // 1. create a new file
1539         std::string filename = "test_move_2.txt";
1540         std::string content = "Test for move use.";
1541         CreateFile(filename, content, state);
1542 
1543         // 2. map file
1544         MappedFile mf(filename);
1545         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1546 
1547         off_t size = mf.Size();
1548         off_t offset = mf.StartOffset();
1549         MapMode mode = mf.GetMode();
1550         const char* hint = mf.GetHint();
1551 
1552         AssertEqual(mf.Unmap(), MAPPED_FILE_ERR_OK,
1553             "mf.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1554         // 3. move to a new object
1555         MappedFile mfNew(std::move(mf));
1556 
1557         // 4. check status and params after move
1558         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1559         AssertFalse((mf.IsNormed()), "mf.IsNormed() did not equal false as expected.", state);
1560 
1561         AssertEqual(mf.Begin(), nullptr, "mf.Begin() did not equal nullptr as expected.", state);
1562         AssertEqual(mf.Size(), MappedFile::DEFAULT_LENGTH,
1563             "mf.Size() did not equal MappedFile::DEFAULT_LENGTH as expected.", state);
1564         AssertEqual(mf.StartOffset(), 0, "mf.StartOffset() did not equal 0 as expected.", state);
1565         AssertEqual(mf.GetMode(), MapMode::DEFAULT,
1566             "mf.GetMode() did not equal MapMode::DEFAULT as expected.", state);
1567         AssertEqual(mf.GetHint(), nullptr, "mf.GetHint() did not equal nullptr as expected.", state);
1568         AssertEqual(mf.GetPath(), "", "mf.GetPath() did not equal "" as expected.", state);
1569 
1570         AssertFalse((mfNew.IsMapped()), "mfNew.IsMapped() did not equal false as expected.", state);
1571         AssertTrue((mfNew.IsNormed()), "mfNew.IsNormed() did not equal true as expected.", state);
1572         AssertEqual(mfNew.Begin(), nullptr, "mfNew.Begin() did not equal nullptr as expected.", state);
1573         AssertEqual(mfNew.Size(), size, "mfNew.Size() did not equal size as expected.", state);
1574         AssertEqual(mfNew.StartOffset(), offset, "mfNew.StartOffset() did not equal offset as expected.", state);
1575         AssertEqual(mfNew.GetMode(), mode, "mfNew.GetMode() did not equal mode as expected.", state);
1576         AssertEqual(mfNew.GetHint(), hint, "mfNew.GetHint() did not equal hint as expected.", state);
1577         AssertEqual(mfNew.GetPath(), filename, "mfNew.GetPath() did not equal filename as expected.", state);
1578 
1579         // 5. Map again
1580         AssertEqual(mfNew.Map(), MAPPED_FILE_ERR_OK,
1581             "mfNew.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1582         // 6. read from mapped file
1583         ReadFromMappedFile(content, mfNew, state);
1584 
1585         // 7. write to mapped file
1586         std::string toWrite("Complete.");
1587         WriteToMappedFile(toWrite, mfNew);
1588         std::string res;
1589         LoadStringFromFile(filename, res);
1590         AssertEqual(res, "Complete.move use.", "res did not equal \"Complete.move use.\" as expected.", state);
1591 
1592         RemoveTestFile(filename);
1593     }
1594     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile002 end.");
1595 }
1596 
1597 /*
1598  * @tc.name: testMoveMappedFile003
1599  * @tc.desc: Test move assignment operator overload.
1600  */
BENCHMARK_F(BenchmarkMappedFileTest,testMoveMappedFile003)1601 BENCHMARK_F(BenchmarkMappedFileTest, testMoveMappedFile003)(benchmark::State& state)
1602 {
1603     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile003 start.");
1604     while (state.KeepRunning()) {
1605         // 1. create a new file
1606         std::string filename = "test_move_3.txt";
1607         std::string content = "Test for move use.";
1608         CreateFile(filename, content, state);
1609 
1610         std::string filename1 = "test_move_4.txt";
1611         std::string content1 = "Test for move use.";
1612         CreateFile(filename1, content1, state);
1613 
1614         // 2. map file
1615         MappedFile mf(filename);
1616         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1617         MappedFile mf1(filename1);
1618         AssertEqual(mf1.Map(), MAPPED_FILE_ERR_OK, "mf1.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1619 
1620         off_t size = mf1.Size();
1621         off_t offset = mf1.StartOffset();
1622         MapMode mode = mf1.GetMode();
1623         char* data = mf1.Begin();
1624         const char* hint = mf1.GetHint();
1625 
1626         // 3. move assignment
1627         mf = std::move(mf1);
1628 
1629         // 4. check status and params after move
1630         AssertTrue((mf.IsMapped()), "mf.IsMapped() did not equal true as expected.", state);
1631         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1632         AssertEqual(mf.Begin(), data, "mf.Begin() did not equal data as expected.", state);
1633         AssertEqual(mf.Size(), size, "mf.Size() did not equal size as expected.", state);
1634         AssertEqual(mf.StartOffset(), offset, "mf.StartOffset() did not equal offset as expected.", state);
1635         AssertEqual(mf.GetMode(), mode, "mf.GetMode() did not equal mode as expected.", state);
1636         AssertEqual(mf.GetHint(), hint, "mf.GetHint() did not equal hint as expected.", state);
1637         AssertEqual(mf.GetPath(), filename1, "mf.GetPath() did not equal filename1 as expected.", state);
1638 
1639         // 5. read from mapped file
1640         ReadFromMappedFile(content1, mf, state);
1641 
1642         // 6. write to mapped file
1643         std::string toWrite("Complete.");
1644         WriteToMappedFile(toWrite, mf);
1645         std::string res;
1646         LoadStringFromFile(filename1, res);
1647         AssertEqual(res, "Complete.move use.", "res did not equal \"Complete.move use.\" as expected.", state);
1648 
1649         RemoveTestFile(filename);
1650         RemoveTestFile(filename1);
1651     }
1652     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile003 end.");
1653 }
1654 
1655 /*
1656  * @tc.name: testMoveMappedFile004
1657  * @tc.desc: Test move assignment operator overload with ummapped region.
1658  */
BENCHMARK_F(BenchmarkMappedFileTest,testMoveMappedFile004)1659 BENCHMARK_F(BenchmarkMappedFileTest, testMoveMappedFile004)(benchmark::State& state)
1660 {
1661     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile004 start.");
1662     while (state.KeepRunning()) {
1663         // 1. create a new file
1664         std::string filename = "test_move_4.txt";
1665         std::string content = "Test for move use.";
1666         CreateFile(filename, content, state);
1667 
1668         std::string filename1 = "test_move_5.txt";
1669         std::string content1 = "Test for move use.";
1670         CreateFile(filename1, content1, state);
1671 
1672         // 2. map file
1673         MappedFile mf(filename);
1674         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1675         MappedFile mf1(filename1);
1676         AssertEqual(mf1.Map(), MAPPED_FILE_ERR_OK, "mf1.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1677 
1678         off_t size = mf1.Size();
1679         off_t offset = mf1.StartOffset();
1680         MapMode mode = mf1.GetMode();
1681         const char* hint = mf1.GetHint();
1682 
1683         // 3. ummap mf1
1684         AssertEqual(mf1.Unmap(), MAPPED_FILE_ERR_OK,
1685             "mf1.Unmap() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1686         // 4. move assignment
1687         mf = std::move(mf1);
1688         // 5. check status and params after move
1689         AssertFalse((mf.IsMapped()), "mf.IsMapped() did not equal false as expected.", state);
1690         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1691         AssertEqual(mf.Begin(), nullptr, "mf.Begin() did not equal nullptr as expected.", state);
1692         AssertEqual(mf.Size(), size, "mf.Size() did not equal size as expected.", state);
1693         AssertEqual(mf.StartOffset(), offset, "mf.StartOffset() did not equal offset as expected.", state);
1694         AssertEqual(mf.GetMode(), mode, "mf.GetMode() did not equal mode as expected.", state);
1695         AssertEqual(mf.GetHint(), hint, "mf.GetHint() did not equal hint as expected.", state);
1696         AssertEqual(mf.GetPath(), filename1, "mf.GetPath() did not equal filename1 as expected.", state);
1697 
1698         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1699         // 6. read from mapped file
1700         ReadFromMappedFile(content1, mf, state);
1701 
1702         // 7. write to mapped file
1703         std::string toWrite("Complete.");
1704         WriteToMappedFile(toWrite, mf);
1705         std::string res;
1706         LoadStringFromFile(filename1, res);
1707         AssertEqual(res, "Complete.move use.", "res did not equal \"Complete.move use.\" as expected.", state);
1708 
1709         RemoveTestFile(filename);
1710         RemoveTestFile(filename1);
1711     }
1712     BENCHMARK_LOGD("MappedFileTest testMoveMappedFile004 end.");
1713 }
1714 
1715 /*
1716  * @tc.name: testNormalize001
1717  * @tc.desc: Test Normalize via changing offset and size.
1718  */
BENCHMARK_F(BenchmarkMappedFileTest,testNormalize001)1719 BENCHMARK_F(BenchmarkMappedFileTest, testNormalize001)(benchmark::State& state)
1720 {
1721     BENCHMARK_LOGD("MappedFileTest testNormalize001 start.");
1722     while (state.KeepRunning()) {
1723         // create a new file
1724         std::string filename = "test_normalize.txt";
1725         std::string content = "Test for normalize use.";
1726         filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
1727         RemoveTestFile(filename);
1728 
1729         const int mapMode1 = -1;
1730         const int mapMode2 = -2;
1731         MappedFile mf(filename, MapMode::DEFAULT, mapMode1, mapMode2);
1732         AssertEqual(mf.Normalize(), ERR_INVALID_VALUE,
1733             "mf.Normalize did not equal ERR_INVALID_VALUE as expected.", state);
1734 
1735         RemoveTestFile(filename);
1736 
1737         filename = "test_normalize1.txt";
1738         content = "Test for normalize1 use.";
1739         CreateFile(filename, content, state);
1740 
1741 
1742         off_t size = 20;
1743         MappedFile mf1(filename, MapMode::DEFAULT, 0, size);
1744         ErrCode res = mf1.Normalize();
1745         AssertEqual(res, MAPPED_FILE_ERR_OK, "res did not equal MAPPED_FILE_ERR_OK as expected.", state);
1746 
1747         RemoveTestFile(filename);
1748     }
1749     BENCHMARK_LOGD("MappedFileTest testNormalize001 end.");
1750 }
1751 
1752 /*
1753  * @tc.name: testClear001
1754  * @tc.desc: Test Clear.
1755  */
BENCHMARK_F(BenchmarkMappedFileTest,testClear001)1756 BENCHMARK_F(BenchmarkMappedFileTest, testClear001)(benchmark::State& state)
1757 {
1758     BENCHMARK_LOGD("MappedFileTest testClear001 start.");
1759     while (state.KeepRunning()) {
1760         // 1. create a new file
1761         std::string filename = "test_clear.txt";
1762         std::string content = "Test for clear use.";
1763         CreateFile(filename, content, state);
1764 
1765 
1766         MappedFile mf1(filename);
1767         // 2. map file
1768         AssertEqual(mf1.Map(), MAPPED_FILE_ERR_OK, "mf1.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1769 
1770         // 3. clear mapping
1771         AssertEqual(mf1.Clear(true), MAPPED_FILE_ERR_OK,
1772             "mf1.Clear(true) did not equal MAPPED_FILE_ERR_OK as expected.", state);
1773         RemoveTestFile(filename);
1774     }
1775     BENCHMARK_LOGD("MappedFileTest testClear001 end.");
1776 }
1777 
1778 /*
1779  * @tc.name: testMoveConstructor001
1780  * @tc.desc: Test Move Constructor.
1781  */
BENCHMARK_F(BenchmarkMappedFileTest,testMoveConstructor001)1782 BENCHMARK_F(BenchmarkMappedFileTest, testMoveConstructor001)(benchmark::State& state)
1783 {
1784     BENCHMARK_LOGD("MappedFileTest testMoveConstructor001 start.");
1785     while (state.KeepRunning()) {
1786         std::string filename = "test_move_assignment.txt";
1787         std::string content = "Test for move assignment use.";
1788         filename.insert(0, SUITE_PATH).insert(0, BASE_PATH);
1789 
1790         AssertTrue((CreateTestFile(filename, content)),
1791             "CreateTestFile(filename, content) did not equal true as expected.", state);
1792 
1793         MappedFile mf(filename);
1794 
1795         AssertEqual(mf.Map(), MAPPED_FILE_ERR_OK, "mf.Map() did not equal MAPPED_FILE_ERR_OK as expected.", state);
1796         AssertTrue((mf.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1797 
1798         MappedFile mf1(std::move(mf));
1799         AssertTrue((mf1.IsNormed()), "mf.IsNormed() did not equal true as expected.", state);
1800         AssertFalse(mf.IsNormed(), "mf.IsNormed() did not equal false as expected.", state);
1801 
1802         RemoveTestFile(filename);
1803     }
1804     BENCHMARK_LOGD("MappedFileTest testMoveConstructor001 end.");
1805 }
1806 }  // namespace
1807 }  // namespace OHOS
1808 // Run the benchmark
1809 BENCHMARK_MAIN();