19762338dSopenharmony_ci/*
29762338dSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
39762338dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49762338dSopenharmony_ci * you may not use this file except in compliance with the License.
59762338dSopenharmony_ci * You may obtain a copy of the License at
69762338dSopenharmony_ci *
79762338dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89762338dSopenharmony_ci *
99762338dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109762338dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119762338dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129762338dSopenharmony_ci * See the License for the specific language governing permissions and
139762338dSopenharmony_ci * limitations under the License.
149762338dSopenharmony_ci */
159762338dSopenharmony_ci
169762338dSopenharmony_ci#include <cstdio>
179762338dSopenharmony_ci#include <thread>
189762338dSopenharmony_ci#include <memory> /* unique_ptr */
199762338dSopenharmony_ci#include <cstring>
209762338dSopenharmony_ci#include "gtest/gtest.h"
219762338dSopenharmony_ci#include "purgeable_mem.h"
229762338dSopenharmony_ci
239762338dSopenharmony_cinamespace OHOS {
249762338dSopenharmony_cinamespace PurgeableMem {
259762338dSopenharmony_ciusing namespace testing;
269762338dSopenharmony_ciusing namespace testing::ext;
279762338dSopenharmony_ci
289762338dSopenharmony_cistatic constexpr int PRINT_INTERVAL_SECONDS = 1;
299762338dSopenharmony_cistatic constexpr int RECLAIM_INTERVAL_SECONDS = 1;
309762338dSopenharmony_cistatic constexpr int MODIFY_INTERVAL_SECONDS = 2;
319762338dSopenharmony_civoid LoopPrintAlphabet(PurgeableMem *pdata, unsigned int loopCount);
329762338dSopenharmony_cibool ReclaimPurgeable(void);
339762338dSopenharmony_civoid LoopReclaimPurgeable(unsigned int loopCount);
349762338dSopenharmony_civoid ModifyPurgMemByBuilder(PurgeableMem *pdata, std::unique_ptr<PurgeableMemBuilder> mod);
359762338dSopenharmony_ci
369762338dSopenharmony_ciclass TestDataBuilder : public PurgeableMemBuilder {
379762338dSopenharmony_cipublic:
389762338dSopenharmony_ci    TestDataBuilder(char start, char end)
399762338dSopenharmony_ci    {
409762338dSopenharmony_ci        this->start = start;
419762338dSopenharmony_ci        this->end = end;
429762338dSopenharmony_ci    }
439762338dSopenharmony_ci
449762338dSopenharmony_ci    bool Build(void *data, size_t size)
459762338dSopenharmony_ci    {
469762338dSopenharmony_ci        if (size <= 0) {
479762338dSopenharmony_ci            return true;
489762338dSopenharmony_ci        }
499762338dSopenharmony_ci        char *str = static_cast<char *>(data);
509762338dSopenharmony_ci        size_t len = 0;
519762338dSopenharmony_ci        for (char ch = start; ch <= end && len < size; ch++) {
529762338dSopenharmony_ci            str[len++] = ch;
539762338dSopenharmony_ci        }
549762338dSopenharmony_ci        str[size - 1] = 0;
559762338dSopenharmony_ci        std::cout << "rebuild addr("<< (unsigned long long)str <<") " <<
569762338dSopenharmony_ci            start << "~" << end << ", data=[" << str << "]" << std::endl;
579762338dSopenharmony_ci        return true;
589762338dSopenharmony_ci    }
599762338dSopenharmony_ci
609762338dSopenharmony_ci    ~TestDataBuilder()
619762338dSopenharmony_ci    {
629762338dSopenharmony_ci        std::cout << "~TestDataBuilder" << std::endl;
639762338dSopenharmony_ci    }
649762338dSopenharmony_ci
659762338dSopenharmony_ciprivate:
669762338dSopenharmony_ci    char start, end;
679762338dSopenharmony_ci};
689762338dSopenharmony_ci
699762338dSopenharmony_ciclass TestDataModifier : public PurgeableMemBuilder {
709762338dSopenharmony_cipublic:
719762338dSopenharmony_ci    TestDataModifier(char from, char to)
729762338dSopenharmony_ci    {
739762338dSopenharmony_ci        this->from = from;
749762338dSopenharmony_ci        this->to = to;
759762338dSopenharmony_ci    }
769762338dSopenharmony_ci
779762338dSopenharmony_ci    bool Build(void *data, size_t size)
789762338dSopenharmony_ci    {
799762338dSopenharmony_ci        char *str = static_cast<char *>(data);
809762338dSopenharmony_ci        for (size_t i = 0; i < size && str[i]; i++) {
819762338dSopenharmony_ci            if (str[i] == from) {
829762338dSopenharmony_ci                str[i] = to;
839762338dSopenharmony_ci            }
849762338dSopenharmony_ci        }
859762338dSopenharmony_ci        return true;
869762338dSopenharmony_ci    }
879762338dSopenharmony_ci
889762338dSopenharmony_ci    ~TestDataModifier()
899762338dSopenharmony_ci    {
909762338dSopenharmony_ci        std::cout << "~TestDataModifier" << std::endl;
919762338dSopenharmony_ci    }
929762338dSopenharmony_ci
939762338dSopenharmony_ciprivate:
949762338dSopenharmony_ci    char from, to;
959762338dSopenharmony_ci};
969762338dSopenharmony_ci
979762338dSopenharmony_ciclass TestBigDataBuilder : public PurgeableMemBuilder {
989762338dSopenharmony_cipublic:
999762338dSopenharmony_ci    explicit TestBigDataBuilder(char target)
1009762338dSopenharmony_ci    {
1019762338dSopenharmony_ci        this->target = target;
1029762338dSopenharmony_ci    }
1039762338dSopenharmony_ci
1049762338dSopenharmony_ci    bool Build(void *data, size_t size)
1059762338dSopenharmony_ci    {
1069762338dSopenharmony_ci        if (size <= 0) {
1079762338dSopenharmony_ci            return true;
1089762338dSopenharmony_ci        }
1099762338dSopenharmony_ci        char *str = static_cast<char *>(data);
1109762338dSopenharmony_ci        size_t len = 0;
1119762338dSopenharmony_ci        for (char ch = target; len < size;) {
1129762338dSopenharmony_ci            str[len++] = ch;
1139762338dSopenharmony_ci        }
1149762338dSopenharmony_ci        str[size - 1] = 0;
1159762338dSopenharmony_ci        return true;
1169762338dSopenharmony_ci    }
1179762338dSopenharmony_ci
1189762338dSopenharmony_ci    ~TestBigDataBuilder()
1199762338dSopenharmony_ci    {
1209762338dSopenharmony_ci        std::cout << "~TestBigDataBuilder" << std::endl;
1219762338dSopenharmony_ci    }
1229762338dSopenharmony_ci
1239762338dSopenharmony_ciprivate:
1249762338dSopenharmony_ci    char target;
1259762338dSopenharmony_ci};
1269762338dSopenharmony_ci
1279762338dSopenharmony_ciclass PurgeableCppTest : public testing::Test {
1289762338dSopenharmony_cipublic:
1299762338dSopenharmony_ci    static void SetUpTestCase();
1309762338dSopenharmony_ci    static void TearDownTestCase();
1319762338dSopenharmony_ci    void SetUp();
1329762338dSopenharmony_ci    void TearDown();
1339762338dSopenharmony_ci};
1349762338dSopenharmony_ci
1359762338dSopenharmony_civoid PurgeableCppTest::SetUpTestCase()
1369762338dSopenharmony_ci{
1379762338dSopenharmony_ci}
1389762338dSopenharmony_ci
1399762338dSopenharmony_civoid PurgeableCppTest::TearDownTestCase()
1409762338dSopenharmony_ci{
1419762338dSopenharmony_ci}
1429762338dSopenharmony_ci
1439762338dSopenharmony_civoid PurgeableCppTest::SetUp()
1449762338dSopenharmony_ci{
1459762338dSopenharmony_ci}
1469762338dSopenharmony_ci
1479762338dSopenharmony_civoid PurgeableCppTest::TearDown()
1489762338dSopenharmony_ci{
1499762338dSopenharmony_ci}
1509762338dSopenharmony_ci
1519762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, MultiObjCreateTest, TestSize.Level1)
1529762338dSopenharmony_ci{
1539762338dSopenharmony_ci    const char alphabetFinal[] = "BBCDEFGHIJKLMNOPQRSTUVWXYZ\0";
1549762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder1 = std::make_unique<TestDataBuilder>('A', 'Z');
1559762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder2 = std::make_unique<TestDataBuilder>('A', 'Z');
1569762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> mod1 = std::make_unique<TestDataModifier>('A', 'B');
1579762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> mod2 = std::make_unique<TestDataModifier>('A', 'B');
1589762338dSopenharmony_ci
1599762338dSopenharmony_ci    PurgeableMem pobj1(27, std::move(builder1));
1609762338dSopenharmony_ci    LoopPrintAlphabet(&pobj1, 1);
1619762338dSopenharmony_ci    ModifyPurgMemByBuilder(&pobj1, std::move(mod1));
1629762338dSopenharmony_ci    LoopPrintAlphabet(&pobj1, 1);
1639762338dSopenharmony_ci    LoopReclaimPurgeable(1);
1649762338dSopenharmony_ci
1659762338dSopenharmony_ci    PurgeableMem pobj2(27, std::move(builder2));
1669762338dSopenharmony_ci    LoopPrintAlphabet(&pobj2, 1);
1679762338dSopenharmony_ci    ModifyPurgMemByBuilder(&pobj2, std::move(mod2));
1689762338dSopenharmony_ci    LoopPrintAlphabet(&pobj2, 1);
1699762338dSopenharmony_ci    LoopReclaimPurgeable(1);
1709762338dSopenharmony_ci
1719762338dSopenharmony_ci    int ret1 = 1;
1729762338dSopenharmony_ci    int ret2 = 1;
1739762338dSopenharmony_ci    int times1 = 0;
1749762338dSopenharmony_ci    int times2 = 0;
1759762338dSopenharmony_ci    while (times1++ < 10) {
1769762338dSopenharmony_ci        if (pobj1.BeginRead()) {
1779762338dSopenharmony_ci            ret1 = strncmp(alphabetFinal, static_cast<char *>(pobj1.GetContent()), 26);
1789762338dSopenharmony_ci            pobj1.EndRead();
1799762338dSopenharmony_ci            break;
1809762338dSopenharmony_ci        } else {
1819762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
1829762338dSopenharmony_ci        }
1839762338dSopenharmony_ci    }
1849762338dSopenharmony_ci
1859762338dSopenharmony_ci    while (times2++ < 10) {
1869762338dSopenharmony_ci        if (pobj2.BeginRead()) {
1879762338dSopenharmony_ci            ret2 = strncmp(alphabetFinal, static_cast<char *>(pobj2.GetContent()), 26);
1889762338dSopenharmony_ci            pobj2.EndRead();
1899762338dSopenharmony_ci            break;
1909762338dSopenharmony_ci        } else {
1919762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
1929762338dSopenharmony_ci        }
1939762338dSopenharmony_ci    }
1949762338dSopenharmony_ci
1959762338dSopenharmony_ci    EXPECT_EQ(ret1, 0);
1969762338dSopenharmony_ci    EXPECT_EQ(ret2, 0);
1979762338dSopenharmony_ci}
1989762338dSopenharmony_ci
1999762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, ReadTest, TestSize.Level1)
2009762338dSopenharmony_ci{
2019762338dSopenharmony_ci    const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0";
2029762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestDataBuilder>('A', 'Z');
2039762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(27, std::move(builder));
2049762338dSopenharmony_ci    LoopReclaimPurgeable(1);
2059762338dSopenharmony_ci
2069762338dSopenharmony_ci    int times = 0;
2079762338dSopenharmony_ci    int ret = 1;
2089762338dSopenharmony_ci    while (times++ < 10) {
2099762338dSopenharmony_ci        if (pobj->BeginRead()) {
2109762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 26);
2119762338dSopenharmony_ci            pobj->EndRead();
2129762338dSopenharmony_ci            break;
2139762338dSopenharmony_ci        } else {
2149762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
2159762338dSopenharmony_ci        }
2169762338dSopenharmony_ci    }
2179762338dSopenharmony_ci    delete pobj;
2189762338dSopenharmony_ci    pobj = nullptr;
2199762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
2209762338dSopenharmony_ci}
2219762338dSopenharmony_ci
2229762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, WriteTest, TestSize.Level1)
2239762338dSopenharmony_ci{
2249762338dSopenharmony_ci    const char alphabet[] = "CCCDEFGHIJKLMNOPQRSTUVWXYZ\0";
2259762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestDataBuilder>('A', 'Z');
2269762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(27, std::move(builder));
2279762338dSopenharmony_ci    LoopReclaimPurgeable(1);
2289762338dSopenharmony_ci
2299762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modA2B = std::make_unique<TestDataModifier>('A', 'B');
2309762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modB2C = std::make_unique<TestDataModifier>('B', 'C');
2319762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modA2B));
2329762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modB2C));
2339762338dSopenharmony_ci
2349762338dSopenharmony_ci    int times = 0;
2359762338dSopenharmony_ci    int ret = 1;
2369762338dSopenharmony_ci    while (times++ < 10) {
2379762338dSopenharmony_ci        if (pobj->BeginRead()) {
2389762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 26);
2399762338dSopenharmony_ci            pobj->EndRead();
2409762338dSopenharmony_ci            break;
2419762338dSopenharmony_ci        } else {
2429762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
2439762338dSopenharmony_ci        }
2449762338dSopenharmony_ci    }
2459762338dSopenharmony_ci    delete pobj;
2469762338dSopenharmony_ci    pobj = nullptr;
2479762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
2489762338dSopenharmony_ci}
2499762338dSopenharmony_ci
2509762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, ReadWriteTest, TestSize.Level1)
2519762338dSopenharmony_ci{
2529762338dSopenharmony_ci    const char alphabet[] = "DDDDEFGHIJKLMNOPQRSTUVWXYZ\0";
2539762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestDataBuilder>('A', 'Z');
2549762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(27, std::move(builder));
2559762338dSopenharmony_ci
2569762338dSopenharmony_ci    LoopReclaimPurgeable(1);
2579762338dSopenharmony_ci    LoopPrintAlphabet(pobj, 1);
2589762338dSopenharmony_ci
2599762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modA2B = std::make_unique<TestDataModifier>('A', 'B');
2609762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modB2C = std::make_unique<TestDataModifier>('B', 'C');
2619762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modC2D = std::make_unique<TestDataModifier>('C', 'D');
2629762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modA2B));
2639762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modB2C));
2649762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modC2D));
2659762338dSopenharmony_ci
2669762338dSopenharmony_ci    int times = 0;
2679762338dSopenharmony_ci    int ret = 1;
2689762338dSopenharmony_ci    while (times++ < 10) {
2699762338dSopenharmony_ci        if (pobj->BeginRead()) {
2709762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 26);
2719762338dSopenharmony_ci            pobj->EndRead();
2729762338dSopenharmony_ci            break;
2739762338dSopenharmony_ci        } else {
2749762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
2759762338dSopenharmony_ci        }
2769762338dSopenharmony_ci    }
2779762338dSopenharmony_ci    delete pobj;
2789762338dSopenharmony_ci    pobj = nullptr;
2799762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
2809762338dSopenharmony_ci}
2819762338dSopenharmony_ci
2829762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, MutiPageReadTest, TestSize.Level1)
2839762338dSopenharmony_ci{
2849762338dSopenharmony_ci    char alphabet[4098];
2859762338dSopenharmony_ci    size_t len = 0;
2869762338dSopenharmony_ci    for (char ch = 'A'; len < 4098;) {
2879762338dSopenharmony_ci        alphabet[len++] = ch;
2889762338dSopenharmony_ci    }
2899762338dSopenharmony_ci    alphabet[4097] = 0;
2909762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestBigDataBuilder>('A');
2919762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(4098, std::move(builder));
2929762338dSopenharmony_ci
2939762338dSopenharmony_ci    LoopReclaimPurgeable(1);
2949762338dSopenharmony_ci
2959762338dSopenharmony_ci    int times = 0;
2969762338dSopenharmony_ci    int ret = 1;
2979762338dSopenharmony_ci    while (times++ < 10) {
2989762338dSopenharmony_ci        if (pobj->BeginRead()) {
2999762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 4097);
3009762338dSopenharmony_ci            pobj->EndRead();
3019762338dSopenharmony_ci            break;
3029762338dSopenharmony_ci        } else {
3039762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
3049762338dSopenharmony_ci        }
3059762338dSopenharmony_ci    }
3069762338dSopenharmony_ci    delete pobj;
3079762338dSopenharmony_ci    pobj = nullptr;
3089762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
3099762338dSopenharmony_ci}
3109762338dSopenharmony_ci
3119762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, MutiPageWriteTest, TestSize.Level1)
3129762338dSopenharmony_ci{
3139762338dSopenharmony_ci    char alphabet[4098];
3149762338dSopenharmony_ci    size_t len = 0;
3159762338dSopenharmony_ci    for (char ch = 'C'; len < 4098;) {
3169762338dSopenharmony_ci        alphabet[len++] = ch;
3179762338dSopenharmony_ci    }
3189762338dSopenharmony_ci    alphabet[4097] = 0;
3199762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestBigDataBuilder>('A');
3209762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(4098, std::move(builder));
3219762338dSopenharmony_ci
3229762338dSopenharmony_ci    LoopReclaimPurgeable(1);
3239762338dSopenharmony_ci
3249762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modA2B = std::make_unique<TestDataModifier>('A', 'B');
3259762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modB2C = std::make_unique<TestDataModifier>('B', 'C');
3269762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modA2B));
3279762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modB2C));
3289762338dSopenharmony_ci
3299762338dSopenharmony_ci    int times = 0;
3309762338dSopenharmony_ci    int ret = 1;
3319762338dSopenharmony_ci    while (times++ < 10) {
3329762338dSopenharmony_ci        if (pobj->BeginRead()) {
3339762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 4097);
3349762338dSopenharmony_ci            pobj->EndRead();
3359762338dSopenharmony_ci            break;
3369762338dSopenharmony_ci        } else {
3379762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
3389762338dSopenharmony_ci        }
3399762338dSopenharmony_ci    }
3409762338dSopenharmony_ci    delete pobj;
3419762338dSopenharmony_ci    pobj = nullptr;
3429762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
3439762338dSopenharmony_ci}
3449762338dSopenharmony_ci
3459762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, MutiPageReadWriteTest, TestSize.Level1)
3469762338dSopenharmony_ci{
3479762338dSopenharmony_ci    char alphabet[4098];
3489762338dSopenharmony_ci    size_t len = 0;
3499762338dSopenharmony_ci    for (char ch = 'D'; len < 4098;) {
3509762338dSopenharmony_ci        alphabet[len++] = ch;
3519762338dSopenharmony_ci    }
3529762338dSopenharmony_ci    alphabet[4097] = 0;
3539762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestBigDataBuilder>('A');
3549762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(4098, std::move(builder));
3559762338dSopenharmony_ci    LoopReclaimPurgeable(1);
3569762338dSopenharmony_ci    LoopPrintAlphabet(pobj, 1);
3579762338dSopenharmony_ci
3589762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modA2B = std::make_unique<TestDataModifier>('A', 'B');
3599762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modB2C = std::make_unique<TestDataModifier>('B', 'C');
3609762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modC2D = std::make_unique<TestDataModifier>('C', 'D');
3619762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modA2B));
3629762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modB2C));
3639762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modC2D));
3649762338dSopenharmony_ci
3659762338dSopenharmony_ci    int times = 0;
3669762338dSopenharmony_ci    int ret = 1;
3679762338dSopenharmony_ci    while (times++ < 10) {
3689762338dSopenharmony_ci        if (pobj->BeginRead()) {
3699762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), 4097);
3709762338dSopenharmony_ci            pobj->EndRead();
3719762338dSopenharmony_ci            break;
3729762338dSopenharmony_ci        } else {
3739762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
3749762338dSopenharmony_ci        }
3759762338dSopenharmony_ci    }
3769762338dSopenharmony_ci    delete pobj;
3779762338dSopenharmony_ci    pobj = nullptr;
3789762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
3799762338dSopenharmony_ci}
3809762338dSopenharmony_ci
3819762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, MutiMorePageReadWriteTest, TestSize.Level1)
3829762338dSopenharmony_ci{
3839762338dSopenharmony_ci    size_t size = 5 * 1024 * 1024;
3849762338dSopenharmony_ci    char *alphabet = (char *)malloc(size);
3859762338dSopenharmony_ci    size_t len = 0;
3869762338dSopenharmony_ci    for (char ch = 'D'; len < size;) {
3879762338dSopenharmony_ci        alphabet[len++] = ch;
3889762338dSopenharmony_ci    }
3899762338dSopenharmony_ci    alphabet[size - 1] = 0;
3909762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestBigDataBuilder>('A');
3919762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(size, std::move(builder));
3929762338dSopenharmony_ci
3939762338dSopenharmony_ci    LoopReclaimPurgeable(1);
3949762338dSopenharmony_ci    LoopPrintAlphabet(pobj, 1);
3959762338dSopenharmony_ci
3969762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modA2B = std::make_unique<TestDataModifier>('A', 'B');
3979762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modB2C = std::make_unique<TestDataModifier>('B', 'C');
3989762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> modC2D = std::make_unique<TestDataModifier>('C', 'D');
3999762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modA2B));
4009762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modB2C));
4019762338dSopenharmony_ci    ModifyPurgMemByBuilder(pobj, std::move(modC2D));
4029762338dSopenharmony_ci
4039762338dSopenharmony_ci    int times = 0;
4049762338dSopenharmony_ci    int ret = 1;
4059762338dSopenharmony_ci    while (times++ < 10) {
4069762338dSopenharmony_ci        if (pobj->BeginRead()) {
4079762338dSopenharmony_ci            ret = strncmp(alphabet, static_cast<char *>(pobj->GetContent()), size - 1);
4089762338dSopenharmony_ci            pobj->EndRead();
4099762338dSopenharmony_ci            break;
4109762338dSopenharmony_ci        } else {
4119762338dSopenharmony_ci            std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl;
4129762338dSopenharmony_ci        }
4139762338dSopenharmony_ci    }
4149762338dSopenharmony_ci    delete pobj;
4159762338dSopenharmony_ci    pobj = nullptr;
4169762338dSopenharmony_ci    free(alphabet);
4179762338dSopenharmony_ci    alphabet = nullptr;
4189762338dSopenharmony_ci    EXPECT_EQ(ret, 0);
4199762338dSopenharmony_ci}
4209762338dSopenharmony_ci
4219762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, InvalidInputSizeTest, TestSize.Level1)
4229762338dSopenharmony_ci{
4239762338dSopenharmony_ci    std::unique_ptr<PurgeableMemBuilder> builder = std::make_unique<TestDataBuilder>('A', 'Z');
4249762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(0, std::move(builder));
4259762338dSopenharmony_ci    LoopReclaimPurgeable(1);
4269762338dSopenharmony_ci    bool ret = pobj->BeginRead();
4279762338dSopenharmony_ci    if (ret) {
4289762338dSopenharmony_ci        pobj->EndRead();
4299762338dSopenharmony_ci    }
4309762338dSopenharmony_ci    delete pobj;
4319762338dSopenharmony_ci    pobj = nullptr;
4329762338dSopenharmony_ci    EXPECT_EQ(ret, false);
4339762338dSopenharmony_ci}
4349762338dSopenharmony_ci
4359762338dSopenharmony_ciHWTEST_F(PurgeableCppTest, InvalidInputBuilderTest, TestSize.Level1)
4369762338dSopenharmony_ci{
4379762338dSopenharmony_ci    PurgeableMem *pobj = new PurgeableMem(27, nullptr);
4389762338dSopenharmony_ci    LoopReclaimPurgeable(1);
4399762338dSopenharmony_ci    bool ret = pobj->BeginRead();
4409762338dSopenharmony_ci    if (ret) {
4419762338dSopenharmony_ci        pobj->EndRead();
4429762338dSopenharmony_ci    }
4439762338dSopenharmony_ci    delete pobj;
4449762338dSopenharmony_ci    pobj = nullptr;
4459762338dSopenharmony_ci    EXPECT_EQ(ret, false);
4469762338dSopenharmony_ci}
4479762338dSopenharmony_ci
4489762338dSopenharmony_civoid LoopPrintAlphabet(PurgeableMem *pdata, unsigned int loopCount)
4499762338dSopenharmony_ci{
4509762338dSopenharmony_ci    std::cout << "inter " << __func__ << std::endl;
4519762338dSopenharmony_ci    for (unsigned int i = 0; i < loopCount; i++) {
4529762338dSopenharmony_ci        if (!pdata->BeginRead()) {
4539762338dSopenharmony_ci            std::cout << __func__ << ": " << i << ". ERROR! BeginRead failed." << std::endl;
4549762338dSopenharmony_ci            break;
4559762338dSopenharmony_ci        }
4569762338dSopenharmony_ci        pdata->EndRead();
4579762338dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::seconds(PRINT_INTERVAL_SECONDS));
4589762338dSopenharmony_ci    }
4599762338dSopenharmony_ci    std::cout << "quit " << __func__ << std::endl;
4609762338dSopenharmony_ci}
4619762338dSopenharmony_ci
4629762338dSopenharmony_cibool ReclaimPurgeable(void)
4639762338dSopenharmony_ci{
4649762338dSopenharmony_ci    FILE *f = fopen("/proc/sys/kernel/purgeable", "w");
4659762338dSopenharmony_ci    if (!f) {
4669762338dSopenharmony_ci        std::cout << __func__ << ": kernel not support" << std::endl;
4679762338dSopenharmony_ci        return false;
4689762338dSopenharmony_ci    }
4699762338dSopenharmony_ci    bool succ = true;
4709762338dSopenharmony_ci    if (fputs("1", f) == EOF) {
4719762338dSopenharmony_ci        succ = false;
4729762338dSopenharmony_ci    }
4739762338dSopenharmony_ci
4749762338dSopenharmony_ci    if (fclose(f) == EOF) {
4759762338dSopenharmony_ci        std::cout << __func__ << ": close file failed" << std::endl;
4769762338dSopenharmony_ci    }
4779762338dSopenharmony_ci
4789762338dSopenharmony_ci    return succ;
4799762338dSopenharmony_ci}
4809762338dSopenharmony_ci
4819762338dSopenharmony_civoid LoopReclaimPurgeable(unsigned int loopCount)
4829762338dSopenharmony_ci{
4839762338dSopenharmony_ci    bool ret = false;
4849762338dSopenharmony_ci    std::cout << "inter " << __func__ << std::endl;
4859762338dSopenharmony_ci    for (unsigned int i = 0; i < loopCount; i++) {
4869762338dSopenharmony_ci        ret = ReclaimPurgeable();
4879762338dSopenharmony_ci        std::cout << __func__ << ": " << i << ". Reclaim result=" << (ret ? "succ" : "fail") << std::endl;
4889762338dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::seconds(RECLAIM_INTERVAL_SECONDS)); /* wait reclaim finish */
4899762338dSopenharmony_ci    }
4909762338dSopenharmony_ci    std::cout << "quit " << __func__ << std::endl;
4919762338dSopenharmony_ci}
4929762338dSopenharmony_ci
4939762338dSopenharmony_civoid ModifyPurgMemByBuilder(PurgeableMem *pdata, std::unique_ptr<PurgeableMemBuilder> mod)
4949762338dSopenharmony_ci{
4959762338dSopenharmony_ci    if (!pdata->BeginWrite()) {
4969762338dSopenharmony_ci        std::cout << __func__ << ": ERROR! BeginWrite failed." << std::endl;
4979762338dSopenharmony_ci        return;
4989762338dSopenharmony_ci    }
4999762338dSopenharmony_ci    std::this_thread::sleep_for(std::chrono::seconds(MODIFY_INTERVAL_SECONDS));
5009762338dSopenharmony_ci    pdata->ModifyContentByBuilder(std::move(mod));
5019762338dSopenharmony_ci    pdata->EndWrite();
5029762338dSopenharmony_ci}
5039762338dSopenharmony_ci} /* namespace PurgeableMem */
5049762338dSopenharmony_ci} /* namespace OHOS */
505