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