1 /*
2  * Copyright (c) 2022 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 #ifdef USE_PURGEABLE_MEMORY
17 #include <thread>
18 
19 #include "gtest/gtest.h"
20 #include "purgeable_mem_utils.h"
21 #include "utils.h"
22 
23 #define private public
24 #define protected public
25 #include "app_state_subscriber.h"
26 #include "mem_mgr_client.h"
27 #include "memory_level_manager.h"
28 #include "memmgr_config_manager.h"
29 #include "purgeable_mem_manager.h"
30 #include "system_memory_level_config.h"
31 #undef private
32 #undef protected
33 
34 namespace OHOS {
35 namespace Memory {
36 namespace {
37 static constexpr int32_t SLEEP_TIME = 500;
38 static constexpr int32_t SLEEP_TIME_LONG = 5000;
39 }
40 using namespace testing;
41 using namespace testing::ext;
42 
43 class AppStateSubscriberTest : public AppStateSubscriber {
44 public:
45     void OnConnected() override;
46     void OnDisconnected() override;
47     void OnAppStateChanged(int32_t pid, int32_t uid, int32_t state) override;
48     void ForceReclaim(int32_t pid, int32_t uid) override;
49     void OnTrim(SystemMemoryLevel level) override;
50     void OnRemoteDied(const wptr<IRemoteObject> &object) override;
51     int OnConnectedCallTimes = 0;
52     int OnDisconnectedCallTimes = 0;
53     int OnAppStateChangedCallTimes = 0;
54     int ForceReclaimCallTimes = 0;
55     int OnTrimCallTimes = 0;
56     int OnRemoteDiedCallTimes = 0;
57 };
58 
59 class PurgeableMemMgrTest : public testing::Test {
60 public:
61     static void SetUpTestCase();
62     static void TearDownTestCase();
63     void SetUp();
64     void TearDown();
SleepForFC()65     inline void SleepForFC()
66     {
67         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
68     }
SleepForFiveSecond()69     inline void SleepForFiveSecond()
70     {
71         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_LONG));
72     }
73     static std::shared_ptr<MemMgrClient> memMgrClient_;
74     static std::vector<std::shared_ptr<AppStateSubscriberTest>> appStateSubscriberTests;
75 };
76 std::vector<std::shared_ptr<AppStateSubscriberTest>> PurgeableMemMgrTest::appStateSubscriberTests =
77     std::vector<std::shared_ptr<AppStateSubscriberTest>>();
OnConnected()78 void AppStateSubscriberTest::OnConnected()
79 {
80     OnConnectedCallTimes++;
81 }
82 
OnDisconnected()83 void AppStateSubscriberTest::OnDisconnected()
84 {
85     OnDisconnectedCallTimes++;
86 }
87 
OnAppStateChanged(int32_t pid,int32_t uid,int32_t state)88 void AppStateSubscriberTest::OnAppStateChanged(int32_t pid, int32_t uid, int32_t state)
89 {
90     OnAppStateChangedCallTimes++;
91 }
92 
ForceReclaim(int32_t pid,int32_t uid)93 void AppStateSubscriberTest::ForceReclaim(int32_t pid, int32_t uid)
94 {
95     ForceReclaimCallTimes++;
96 }
97 
OnTrim(SystemMemoryLevel level)98 void AppStateSubscriberTest::OnTrim(SystemMemoryLevel level)
99 {
100     OnTrimCallTimes++;
101 }
102 
OnRemoteDied(const wptr<IRemoteObject> & object)103 void AppStateSubscriberTest::OnRemoteDied(const wptr<IRemoteObject> &object)
104 {
105     OnRemoteDiedCallTimes++;
106 }
107 
SetUpTestCase()108 void PurgeableMemMgrTest::SetUpTestCase()
109 {
110 }
111 
TearDownTestCase()112 void PurgeableMemMgrTest::TearDownTestCase()
113 {
114 }
115 
SetUp()116 void PurgeableMemMgrTest::SetUp()
117 {
118 }
119 
TearDown()120 void PurgeableMemMgrTest::TearDown()
121 {
122     for (auto appStateSubscriberTest_ : appStateSubscriberTests) {
123         MemMgrClient::GetInstance().UnsubscribeAppState(*appStateSubscriberTest_);
124     }
125     appStateSubscriberTests.clear();
126 }
127 
128 class PurgeableMemUtilsTest : public testing::Test {
129 public:
130     static void SetUpTestCase();
131     static void TearDownTestCase();
132     void SetUp();
133     void TearDown();
134 };
135 
SetUpTestCase()136 void PurgeableMemUtilsTest::SetUpTestCase()
137 {
138 }
139 
TearDownTestCase()140 void PurgeableMemUtilsTest::TearDownTestCase()
141 {
142 }
143 
SetUp()144 void PurgeableMemUtilsTest::SetUp()
145 {
146 }
147 
TearDown()148 void PurgeableMemUtilsTest::TearDown()
149 {
150 }
151 
152 HWTEST_F(PurgeableMemMgrTest, SubscribeAppState_Test, TestSize.Level1)
153 {
154     std::shared_ptr<AppStateSubscriberTest> appStateSubscriberTest_1 = std::make_shared<AppStateSubscriberTest>();
155     EXPECT_NE(appStateSubscriberTest_1, nullptr);
156     MemMgrClient::GetInstance().SubscribeAppState(*appStateSubscriberTest_1);
157     appStateSubscriberTests.emplace_back(appStateSubscriberTest_1);
158     SleepForFC();
159     EXPECT_EQ(appStateSubscriberTest_1->OnConnectedCallTimes, 1);
160     MemMgrClient::GetInstance().SubscribeAppState(*appStateSubscriberTest_1);
161     SleepForFC();
162     EXPECT_EQ(appStateSubscriberTest_1->OnConnectedCallTimes, 1);
163     std::shared_ptr<AppStateSubscriberTest> appStateSubscriberTest_2 = std::make_shared<AppStateSubscriberTest>();
164     EXPECT_NE(appStateSubscriberTest_2, nullptr);
165     MemMgrClient::GetInstance().SubscribeAppState(*appStateSubscriberTest_2);
166     appStateSubscriberTests.emplace_back(appStateSubscriberTest_2);
167     SleepForFC();
168     EXPECT_EQ(appStateSubscriberTest_1->OnConnectedCallTimes, 1);
169     EXPECT_EQ(appStateSubscriberTest_2->OnConnectedCallTimes, 1);
170 }
171 
172 HWTEST_F(PurgeableMemMgrTest, UnsubscribeAppState_Test, TestSize.Level1)
173 {
174     std::shared_ptr<AppStateSubscriberTest> appStateSubscriberTest_1 = std::make_shared<AppStateSubscriberTest>();
175     EXPECT_NE(appStateSubscriberTest_1, nullptr);
176     MemMgrClient::GetInstance().SubscribeAppState(*appStateSubscriberTest_1);
177     appStateSubscriberTests.emplace_back(appStateSubscriberTest_1);
178     SleepForFC();
179     MemMgrClient::GetInstance().UnsubscribeAppState(*appStateSubscriberTest_1);
180     SleepForFC();
181     EXPECT_EQ(appStateSubscriberTest_1->OnDisconnectedCallTimes, 1);
182 }
183 
184 HWTEST_F(PurgeableMemMgrTest, AppStateListener_Test, TestSize.Level1)
185 {
186     auto subscriber = AppStateSubscriberTest();
187     auto subscriberImpl = std::make_shared<AppStateSubscriber::AppStateSubscriberImpl>(subscriber);
188     subscriberImpl->recipient_ = sptr<AppStateSubscriber::AppStateSubscriberImpl::DeathRecipient>(
189         new AppStateSubscriber::AppStateSubscriberImpl::DeathRecipient(*subscriberImpl));
190     subscriberImpl->OnConnected();
191     EXPECT_EQ(subscriber.OnConnectedCallTimes, 1);
192     subscriberImpl->OnDisconnected();
193     EXPECT_EQ(subscriber.OnDisconnectedCallTimes, 1);
194     SystemMemoryLevel level = SystemMemoryLevel::MEMORY_LEVEL_MODERATE;
195     subscriberImpl->OnTrim(level);
196     EXPECT_EQ(subscriber.OnTrimCallTimes, 1);
197     int32_t pid = 2001;
198     int32_t uid = 20012001;
199     int32_t state = 1;
200     subscriberImpl->OnAppStateChanged(pid, uid, state);
201     EXPECT_EQ(subscriber.OnAppStateChangedCallTimes, 1);
202     subscriberImpl->ForceReclaim(pid, uid);
203     EXPECT_EQ(subscriber.ForceReclaimCallTimes, 1);
204     subscriberImpl->recipient_->OnRemoteDied(nullptr);
205     EXPECT_EQ(subscriber.OnRemoteDiedCallTimes, 1);
206 }
207 
208 HWTEST_F(PurgeableMemUtilsTest, GetPurgeableHeapInfoTest, TestSize.Level1)
209 {
210     int reclaimableKB;
211     bool ret = PurgeableMemUtils::GetInstance().GetPurgeableHeapInfo(reclaimableKB);
212     printf("ret=%d,reclaimableKB=%dKB\n", ret, reclaimableKB);
213     ret = ret && reclaimableKB >= 0;
214     EXPECT_EQ(ret, true);
215 }
216 
217 HWTEST_F(PurgeableMemUtilsTest, GetProcPurgeableHeapInfoTest, TestSize.Level1)
218 {
219     int reclaimableKB;
220     bool ret = PurgeableMemUtils::GetInstance().GetProcPurgeableHeapInfo(1, reclaimableKB);
221     printf("pid=%d,reclaimableKB=%dKB\n", 1, reclaimableKB);
222     ret = ret && reclaimableKB >= 0;
223     EXPECT_EQ(ret, true);
224 }
225 
226 HWTEST_F(PurgeableMemUtilsTest, PurgeHeapAllTest, TestSize.Level1)
227 {
228     bool ret = PurgeableMemUtils::GetInstance().PurgeHeapAll();
229     EXPECT_EQ(ret, true);
230 }
231 
232 HWTEST_F(PurgeableMemUtilsTest, PurgeHeapAllTestDebug1, TestSize.Level1)
233 {
234     const char *path = PurgeableMemUtils::PATH_PURGE_HEAP.c_str();
235     int fd = open(path, O_WRONLY);
236     if (fd == -1) {
237         printf("open %s failed!\n", path);
238     }
239     ASSERT_NE(fd, -1);
240     close(fd);
241 }
242 
243 HWTEST_F(PurgeableMemUtilsTest, PurgeHeapMemcgTest, TestSize.Level1)
244 {
245     std::string memcgPath = "/dev/memcg";
246     bool ret = PurgeableMemUtils::GetInstance().PurgeHeapMemcg(memcgPath, 1024);
247     EXPECT_EQ(ret, true);
248 }
249 
250 HWTEST_F(PurgeableMemUtilsTest, PurgeAshmAllTest, TestSize.Level1)
251 {
252     bool ret = PurgeableMemUtils::GetInstance().PurgeAshmAll();
253     EXPECT_EQ(ret, true);
254 }
255 
256 HWTEST_F(PurgeableMemUtilsTest, PurgeAshmByIdWithTimeTest, TestSize.Level1)
257 {
258     std::string idWithTime = "1000 1000";
259     bool ret = PurgeableMemUtils::GetInstance().PurgeAshmByIdWithTime(idWithTime);
260     EXPECT_EQ(ret, true);
261 }
262 } //namespace Memory
263 } //namespace OHOS
264 #endif // USE_PURGEABLE_MEMORY