1 /*
2 * Copyright (c) 2025 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 <gtest/gtest.h>
17 #include <gmock/gmock.h>
18
19 #include <unordered_set>
20
21 #include <unistd.h>
22 #include <sys/stat.h>
23 #define private public
24 #include "resource_overlimit_mgr.h"
25
26 #include <application_context.h>
27 #include <hilog/log.h>
28 #include "file_util.h"
29 #include "hiappevent_base.h"
30 #undef private
31
32 using namespace testing;
33 using namespace testing::ext;
34 using namespace OHOS;
35 using namespace OHOS::HiviewDFX;
36 using namespace OHOS::AbilityRuntime;
37
38 namespace OHOS {
39 namespace {
40 std::shared_ptr<AbilityRuntime::ApplicationContext> g_applicationContext = nullptr;
41 constexpr int RETURN_CNT_1 = 1;
42 constexpr int RETURN_CNT_2 = 2;
43 constexpr int RETURN_CNT_8 = 8;
44 constexpr int RETURN_CNT_14 = 14;
45 constexpr const char* const TEST_PATH = "/data/local/tmp/rawheap";
46
CreateTestDir()47 void CreateTestDir()
48 {
49 std::string path = TEST_PATH;
50 if (access(path.c_str(), F_OK) != 0) {
51 constexpr mode_t defaultMode = 0755;
52 if (mkdir(path.c_str(), defaultMode) != 0) {
53 perror("mkdir failed");
54 }
55 }
56 }
57
RemoveTestDir()58 void RemoveTestDir()
59 {
60 std::string path = TEST_PATH;
61 if (access(path.c_str(), F_OK) == 0) {
62 if (rmdir(path.c_str()) != 0) {
63 perror("rmdir failed");
64 }
65 }
66 }
67 }
68
69 namespace AbilityRuntime {
GetApplicationContext()70 std::shared_ptr<ApplicationContext> Context::GetApplicationContext()
71 {
72 return g_applicationContext;
73 }
74 } // namespace AbilityRuntime
75
76 class ApplicationContextMock : public ApplicationContext {
77 public:
78 MOCK_METHOD0(GetCacheDir, std::string());
79 };
80
81 namespace HiviewDFX {
82 class GetRawheapDirTest : public ::testing::Test {
83 protected:
SetUp()84 void SetUp() override
85 {
86 CreateTestDir();
87 }
88
TearDown()89 void TearDown() override
90 {
91 g_applicationContext = nullptr;
92 RemoveTestDir();
93 }
94 };
95
96 /**
97 * @tc.name : GetRawheapDirTest_ShouldReturnEmpty_WhenContextIsNullptr
98 * @tc.number: GetRawheapDirTest_001
99 * @tc.desc : context == nullptr, GetRawheapDir 应返回 ""
100 */
101 HWTEST_F(GetRawheapDirTest, GetRawheapDirTest_001, TestSize.Level0)
102 {
103 g_applicationContext = nullptr;
104
105 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().GetRawheapDir().empty());
106 }
107
108 /**
109 * @tc.name : GetRawheapDir_ShouldReturnEmpty_WhenContextIsNullptr
110 * @tc.number: GetRawheapDirTest_002
111 * @tc.desc : GetCacheDir.empty()时, GetRawheapDir 应返回 ""
112 */
113 HWTEST_F(GetRawheapDirTest, GetRawheapDirTest_002, TestSize.Level0)
114 {
115 ApplicationContextMock *contextMock = new ApplicationContextMock();
116 ASSERT_NE(contextMock, nullptr);
117 EXPECT_CALL(*contextMock, GetCacheDir())
118 .Times(RETURN_CNT_1)
119 .WillRepeatedly(::testing::Return(""));
120 g_applicationContext.reset(contextMock);
121
122 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().GetRawheapDir().empty());
123 }
124
125 /**
126 * @tc.name : GetRawheapDir_ShouldReturnEmpty_WhenPathNotExist
127 * @tc.number: GetRawheapDirTest_003
128 * @tc.desc : 测试当rawheap时, GetRawheapDir 应返回 ""
129 */
130 HWTEST_F(GetRawheapDirTest, GetRawheapDirTest_003, TestSize.Level0)
131 {
132 ApplicationContextMock *contextMock = new ApplicationContextMock();
133 ASSERT_NE(contextMock, nullptr);
134 EXPECT_CALL(*contextMock, GetCacheDir())
135 .Times(RETURN_CNT_2)
136 .WillRepeatedly(::testing::Return("/data/storage/el2/base/cache"));
137 g_applicationContext.reset(contextMock);
138
139 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().GetRawheapDir().empty());
140 }
141
142 /**
143 * @tc.name : GetRawheapDir_ShouldReturnPath_WhenPathExist
144 * @tc.number: GetRawheapDirTest_004
145 * @tc.desc : 测试当rawheap存在时, GetRawheapDir 应返回 TEST_PATH
146 */
147 HWTEST_F(GetRawheapDirTest, GetRawheapDirTest_004, TestSize.Level0)
148 {
149 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
150
151 ApplicationContextMock *contextMock = new ApplicationContextMock();
152 ASSERT_NE(contextMock, nullptr);
153 EXPECT_CALL(*contextMock, GetCacheDir())
154 .Times(RETURN_CNT_2)
155 .WillRepeatedly(::testing::Return("/data/local/tmp"));
156 g_applicationContext.reset(contextMock);
157
158 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().GetRawheapDir(), TEST_PATH);
159 }
160
161 // SetRunningId
162 class SetRunningIdTest : public ::testing::Test {
163 protected:
SetUp()164 void SetUp() override {}
TearDown()165 void TearDown() override {}
166 };
167
168 /**
169 * @tc.name : SetRunningIdTest_ShouldReturnEmpty_WhenInputEmpty
170 * @tc.number: SetRunningIdTest_001
171 * @tc.desc : id == nullptr, runningId_ 应等于 ""
172 */
173 HWTEST_F(SetRunningIdTest, SetRunningIdTest_001, TestSize.Level0)
174 {
175 ResourceOverlimitMgr::GetInstance().SetRunningId("");
176 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().runningId_.empty());
177 ResourceOverlimitMgr::GetInstance().SetRunningId("testValue");
178 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().runningId_, "testValue");
179 }
180
181 // IsValid
182 class IsValidTest : public ::testing::Test {
183 protected:
SetUp()184 void SetUp() override {}
TearDown()185 void TearDown() override {}
186 };
187
188 /**
189 * @tc.name : IsValidTest_ShouldReturnFalse_WhenKeyInvalid
190 * @tc.number: IsValidTest_001
191 * @tc.desc : 当key invalid, return false
192 */
193 HWTEST_F(IsValidTest, IsValidTest_001, TestSize.Level0)
194 {
195 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("invalid", "event"));
196 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("invalid", "event_rawheap"));
197 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("invalid", "invalid too"));
198 }
199
200 /**
201 * @tc.name : IsValidTest_ShouldReturnFalse_WhenKeyValidButValueInvalid
202 * @tc.number: IsValidTest_002
203 * @tc.desc : key valid, value invalid, then return false
204 */
205 HWTEST_F(IsValidTest, IsValidTest_002, TestSize.Level0)
206 {
207 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "invalid"));
208 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "invalid too"));
209 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "even"));
210 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "eventt"));
211 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "eevent"));
212 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "eventrawheap"));
213 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "rawheap"));
214 EXPECT_FALSE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", ""));
215 }
216
217 /**
218 * @tc.name : IsValidTest_ShouldReturnFalse_WhenKeyValidAndValueValid
219 * @tc.number: IsValidTest_003
220 * @tc.desc : key valid, value valid, then return true
221 */
222 HWTEST_F(IsValidTest, IsValidTest_003, TestSize.Level0)
223 {
224 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "event"));
225 EXPECT_TRUE(ResourceOverlimitMgr::GetInstance().IsValid("js_heap_logtype", "event_rawheap"));
226 }
227
228 // UpdateProperty
229 class UpdatePropertyTest : public ::testing::Test {
230 protected:
SetUp()231 void SetUp() override
232 {
233 ResourceOverlimitMgr::GetInstance().runningId_ = "";
234 CreateTestDir();
235 }
236
TearDown()237 void TearDown() override
238 {
239 ResourceOverlimitMgr::GetInstance().runningId_ = "";
240 RemoveTestDir();
241 g_applicationContext = nullptr;
242 }
243 };
244
245 /**
246 * @tc.name : UpdatePropertyTest_ShouldReturnERROR_UNKNOWN_WhenRunningId_Empty
247 * @tc.number: UpdatePropertyTest_001
248 * @tc.desc : runningId_ empty, return ERROR_UNKNOWN
249 */
250 HWTEST_F(UpdatePropertyTest, UpdatePropertyTest_001, TestSize.Level0)
251 {
252 ResourceOverlimitMgr::GetInstance().runningId_ = "";
253 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.key", "value"), ErrorCode::ERROR_UNKNOWN);
254 }
255
256 /**
257 * @tc.name : UpdatePropertyTest_ShouldReturnERROR_UNKNOWN_WhenRawheapNotExist
258 * @tc.number: UpdatePropertyTest_002
259 * @tc.desc : not exist rawheap dir, return ERROR_UNKNOWN
260 */
261 HWTEST_F(UpdatePropertyTest, UpdatePropertyTest_002, TestSize.Level0)
262 {
263 RemoveTestDir();
264 ASSERT_NE(access(TEST_PATH, F_OK), 0);
265 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
266
267 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.key", "value"), ErrorCode::ERROR_UNKNOWN);
268 }
269
270 /**
271 * @tc.name : UpdatePropertyTest_ShouldReturnERROR_UNKNOWN_WhenPropertyInvalid
272 * @tc.number: UpdatePropertyTest_003
273 * @tc.desc : property invalid, return ERROR_UNKNOWN
274 */
275 HWTEST_F(UpdatePropertyTest, UpdatePropertyTest_003, TestSize.Level0)
276 {
277 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
278 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
279 ApplicationContextMock *contextMock = new ApplicationContextMock();
280 ASSERT_NE(contextMock, nullptr);
281 EXPECT_CALL(*contextMock, GetCacheDir())
282 .Times(RETURN_CNT_14)
283 .WillRepeatedly(::testing::Return("/data/local/tmp"));
284 g_applicationContext.reset(contextMock);
285
286 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("key", "value"), ErrorCode::ERROR_UNKNOWN);
287 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("key.key", "value"), ErrorCode::ERROR_UNKNOWN);
288 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("1", "value"), ErrorCode::ERROR_UNKNOWN);
289 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("js_heap_logtype", "1"), ErrorCode::ERROR_UNKNOWN);
290 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("", ""), ErrorCode::ERROR_UNKNOWN);
291 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("1", ""), ErrorCode::ERROR_UNKNOWN);
292 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("", "1"), ErrorCode::ERROR_UNKNOWN);
293 }
294
295 /**
296 * @tc.name : UpdatePropertyTest_ShouldReturn0_WhenPropertyValid
297 * @tc.number: UpdatePropertyTest_004
298 * @tc.desc : property valid, return 0
299 */
300 HWTEST_F(UpdatePropertyTest, UpdatePropertyTest_004, TestSize.Level0)
301 {
302 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
303 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
304 ApplicationContextMock *contextMock = new ApplicationContextMock();
305 ASSERT_NE(contextMock, nullptr);
306 EXPECT_CALL(*contextMock, GetCacheDir())
307 .Times(RETURN_CNT_8)
308 .WillRepeatedly(::testing::Return("/data/local/tmp"));
309 g_applicationContext.reset(contextMock);
310
311 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.js_heap_logtype", "value"), 0);
312 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.event_config.js_heap_logtype", "event_rawheap"),
313 0);
314 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.event_config.js_heap_logtype", "event"), 0);
315 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().UpdateProperty("user.event_config.js_heap_logtype", "event_invalid"),
316 0);
317 }
318
319 // SetEventConfig
320 class SetEventConfigTest : public ::testing::Test {
321 protected:
SetUp()322 void SetUp() override
323 {
324 ResourceOverlimitMgr::GetInstance().runningId_ = "";
325 CreateTestDir();
326 }
327
TearDown()328 void TearDown() override
329 {
330 ResourceOverlimitMgr::GetInstance().runningId_ = "";
331 RemoveTestDir();
332 g_applicationContext = nullptr;
333 }
334 };
335
336 /**
337 * @tc.name : SetEventConfigTest_ShouldReturnERROR_UNKNOWN_WhenConfigMapSizeis1AndInValid
338 * @tc.number: SetEventConfigTest_001
339 * @tc.desc : configMap.size() == 1 invalid, return ERROR_UNKNOWN
340 */
341 HWTEST_F(SetEventConfigTest, SetEventConfigTest_001, TestSize.Level0)
342 {
343 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
344 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
345 ApplicationContextMock *contextMock = new ApplicationContextMock();
346 ASSERT_NE(contextMock, nullptr);
347 g_applicationContext.reset(contextMock);
348
349 std::map<std::string, std::string> configMap = {{"invalid_key", "invalid_value"}};
350 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().SetEventConfig(configMap), ErrorCode::ERROR_UNKNOWN);
351 }
352
353 /**
354 * @tc.name : SetEventConfigTest_ShouldReturn0_WhenConfigMapSizeis1AndValid
355 * @tc.number: SetEventConfigTest_002
356 * @tc.desc : configMap.size() == 1, value valid, return 0
357 */
358 HWTEST_F(SetEventConfigTest, SetEventConfigTest_002, TestSize.Level0)
359 {
360 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
361 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
362 ApplicationContextMock *contextMock = new ApplicationContextMock();
363 ASSERT_NE(contextMock, nullptr);
364 EXPECT_CALL(*contextMock, GetCacheDir())
365 .Times(RETURN_CNT_2)
366 .WillRepeatedly(::testing::Return("/data/local/tmp"));
367 g_applicationContext.reset(contextMock);
368
369 std::map<std::string, std::string> configMap = {{"js_heap_logtype", "event"}};
370 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().SetEventConfig(configMap), 0);
371 }
372
373 /**
374 * @tc.name : SetEventConfigTest_ShouldReturnERROR_UNKNOWN_WhenConfigMapSizeis0
375 * @tc.number: SetEventConfigTest_003
376 * @tc.desc : configMap.size() == 0, return ERROR_UNKNOWN
377 */
378 HWTEST_F(SetEventConfigTest, SetEventConfigTest_003, TestSize.Level0)
379 {
380 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
381 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
382 ApplicationContextMock *contextMock = new ApplicationContextMock();
383 ASSERT_NE(contextMock, nullptr);
384 g_applicationContext.reset(contextMock);
385
386 std::map<std::string, std::string> configMap;
387 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().SetEventConfig(configMap), ErrorCode::ERROR_UNKNOWN);
388 }
389
390 /**
391 * @tc.name : SetEventConfigTest_ShouldReturn0_WhenConfigMapSizeis2And1valid1invalid
392 * @tc.number: SetEventConfigTest_004
393 * @tc.desc : configMap.size() == 2, configMap[0] valid, configMap[1] invalid, return 0
394 */
395 HWTEST_F(SetEventConfigTest, SetEventConfigTest_004, TestSize.Level0)
396 {
397 ASSERT_EQ(access(TEST_PATH, F_OK), 0);
398 ResourceOverlimitMgr::GetInstance().runningId_ = "5555";
399 ApplicationContextMock *contextMock = new ApplicationContextMock();
400 ASSERT_NE(contextMock, nullptr);
401 EXPECT_CALL(*contextMock, GetCacheDir())
402 .Times(RETURN_CNT_2)
403 .WillRepeatedly(::testing::Return("/data/local/tmp"));
404 g_applicationContext.reset(contextMock);
405
406 std::map<std::string, std::string> configMap {
407 {"js_heap_logtype", "event"},
408 {"invalid", "invalid"},
409 };
410 EXPECT_EQ(ResourceOverlimitMgr::GetInstance().SetEventConfig(configMap), 0);
411 }
412 } // HiviewDFX
413 } // namespace OHOS
414