1 /*
2 * Copyright (c) 2022-2024 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 "ecmascript/dfx/hprof/heap_profiler_interface.h"
17 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
18 #include "ecmascript/dfx/vmstat/runtime_stat.h"
19 #include "ecmascript/dfx/hprof/heap_profiler.h"
20 #include "ecmascript/mem/heap-inl.h"
21 #include "ecmascript/mem/concurrent_marker.h"
22 #include "ecmascript/mem/concurrent_sweeper.h"
23 #include "ecmascript/napi/include/dfx_jsnapi.h"
24 #include "ecmascript/tests/test_helper.h"
25 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
26 #include "ecmascript/dfx/tracing/tracing.h"
27
28 using namespace panda;
29 using namespace panda::ecmascript;
30
31 namespace panda::test {
32 using FunctionForRef = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
33 class DFXJSNApiTests : public testing::Test {
34 public:
SetUpTestCase()35 static void SetUpTestCase()
36 {
37 GTEST_LOG_(INFO) << "SetUpTestCase";
38 }
39
TearDownTestCase()40 static void TearDownTestCase()
41 {
42 GTEST_LOG_(INFO) << "TearDownCase";
43 }
44
SetUp()45 void SetUp() override
46 {
47 TestHelper::CreateEcmaVMWithScope(vm_, thread_, scope_);
48 vm_->GetJSThread()->GetEcmaVM()->SetRuntimeStatEnable(true);
49 vm_->SetEnableForceGC(false);
50 }
51
TearDown()52 void TearDown() override
53 {
54 TestHelper::DestroyEcmaVMWithScope(vm_, scope_);
55 }
56
57 protected:
58 EcmaVM *vm_ {nullptr};
59 JSThread *thread_ = {nullptr};
60 EcmaHandleScope *scope_ {nullptr};
61 };
62
MatchJSONLineHeader(std::fstream & fs,const std::string filePath,int lineNum,CString lineContent)63 bool MatchJSONLineHeader(std::fstream &fs, const std::string filePath, int lineNum, CString lineContent)
64 {
65 CString tempLineContent = "";
66 int lineCount = 1;
67 fs.open(filePath.c_str(), std::ios::in);
68 while (getline(fs, tempLineContent)) {
69 if (lineNum == lineCount && tempLineContent.find(lineContent) != CString::npos) {
70 fs.close();
71 fs.clear();
72 return true;
73 }
74 lineCount++;
75 }
76 fs.close();
77 fs.clear();
78 return false;
79 }
80
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_001)81 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_001)
82 {
83 const std::string filePath = "DFXJSNApiTests_json_001.heapsnapshot";
84 std::fstream outputString(filePath, std::ios::out);
85 outputString.close();
86 outputString.clear();
87
88 std::fstream inputFile {};
89 EXPECT_TRUE(inputFile.good());
90
91 DumpSnapShotOption dumpOption;
92 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
93 dumpOption.isVmMode = true;
94 dumpOption.isPrivate = false;
95 dumpOption.captureNumericValue = false;
96 DFXJSNApi::DumpHeapSnapshot(vm_, filePath, dumpOption);
97 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 1, "{\"snapshot\":"));
98 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 2, "{\"meta\":"));
99 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 3, "{\"node_fields\":"));
100 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 4, "\"node_types\":"));
101 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 5, "\"edge_fields\":"));
102 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 6, "\"edge_types\":"));
103 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 7, "\"trace_function_info_fields\":"));
104 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 8, "\"trace_node_fields\":"));
105 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 9, "\"sample_fields\":"));
106 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 10, "\"location_fields\":"));
107 std::remove(filePath.c_str());
108 }
109
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_002)110 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_002)
111 {
112 const std::string filePath = "DFXJSNApiTests_json_002.heapsnapshot";
113 std::fstream outputString(filePath, std::ios::out);
114 outputString.close();
115 outputString.clear();
116
117 ecmascript::FileStream stream(filePath);
118 EXPECT_TRUE(stream.Good());
119
120 ecmascript::Progress *progress = nullptr;
121 std::fstream fStream {};
122 EXPECT_TRUE(fStream.good());
123
124 DumpSnapShotOption dumpOption;
125 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
126 dumpOption.isVmMode = true;
127 dumpOption.isPrivate = false;
128 dumpOption.captureNumericValue = false;
129 DFXJSNApi::DumpHeapSnapshot(vm_, &stream, dumpOption, progress);
130 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 1, "{\"snapshot\":"));
131 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 2, "{\"meta\":"));
132 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 3, "{\"node_fields\":"));
133 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 4, "\"node_types\":"));
134 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 5, "\"edge_fields\":"));
135 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 6, "\"edge_types\":"));
136 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 7, "\"trace_function_info_fields\":"));
137 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 8, "\"trace_node_fields\":"));
138 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 9, "\"sample_fields\":"));
139 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 10, "\"location_fields\":"));
140 std::remove(filePath.c_str());
141 }
142
HWTEST_F_L0(DFXJSNApiTests,BuildNativeAndJsStackTrace)143 HWTEST_F_L0(DFXJSNApiTests, BuildNativeAndJsStackTrace)
144 {
145 bool result = false;
146 std::string stackTraceStr = "stack_trace_str";
147 result = DFXJSNApi::BuildNativeAndJsStackTrace(vm_, stackTraceStr);
148 #if defined(ENABLE_EXCEPTION_BACKTRACE)
149 EXPECT_FALSE(stackTraceStr.empty());
150 EXPECT_TRUE(result);
151 #else
152 EXPECT_TRUE(stackTraceStr.empty());
153 EXPECT_FALSE(result);
154 #endif
155 }
156
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackTrace)157 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackTrace)
158 {
159 std::string stackTraceStr = "stack_trace_str";
160 bool result = DFXJSNApi::BuildJsStackTrace(vm_, stackTraceStr);
161 #if defined(ENABLE_EXCEPTION_BACKTRACE)
162 EXPECT_FALSE(stackTraceStr.empty());
163 EXPECT_TRUE(result);
164 #else
165 EXPECT_TRUE(stackTraceStr.empty());
166 EXPECT_FALSE(result);
167 #endif
168 }
169
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_001)170 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_001)
171 {
172 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
173 vm_->SetEnableForceGC(false);
174
175 auto factory = vm_->GetFactory();
176 bool isVmMode = true;
177 bool traceAllocation = false;
178 double timeInterval = 50; // 50 : time interval 50 ms
179 ecmascript::FileStream *stream = nullptr;
180 bool startResult = false;
181 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
182 EXPECT_TRUE(startResult);
183
184 sleep(1);
185 int count = 300;
186 while (count-- > 0) {
187 JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
188 JSHandle<EcmaString> string = factory->NewFromASCII("Start_Stop_HeapTracking_001_TestString");
189 factory->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
190 }
191 const std::string filePath = "Start_Stop_HeapTracking_001.heaptimeline";
192 std::fstream outputString(filePath, std::ios::out);
193 outputString.close();
194 outputString.clear();
195
196 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, filePath);
197 EXPECT_TRUE(stopResult);
198
199 std::fstream inputStream(filePath, std::ios::in);
200 std::string line;
201 std::string emptySample = "\"samples\":";
202 std::string firstSample = "\"samples\":[0, ";
203 bool isFind = false;
204 while (getline(inputStream, line)) {
205 if (line.substr(0U, emptySample.size()) == emptySample) {
206 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
207 isFind = true;
208 }
209 }
210 EXPECT_TRUE(isFind);
211
212 inputStream.close();
213 inputStream.clear();
214 std::remove(filePath.c_str());
215 vm_->SetEnableForceGC(true);
216 }
217
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_002)218 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_002)
219 {
220 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
221 vm_->SetEnableForceGC(false);
222
223 auto factory = vm_->GetFactory();
224 bool isVmMode = true;
225 bool traceAllocation = false;
226 double timeInterval = 50; // 50 : time interval 50 ms
227 ecmascript::FileStream *stream = nullptr;
228 bool startResult = false;
229 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
230 EXPECT_TRUE(startResult);
231
232 sleep(1);
233 int count = 300;
234 while (count-- > 0) {
235 factory->NewJSAsyncFuncObject();
236 factory->NewJSSymbol();
237 }
238 const std::string filePath = "Start_Stop_HeapTracking_002.heaptimeline";
239 std::fstream outputString(filePath, std::ios::out);
240 outputString.close();
241 outputString.clear();
242
243 ecmascript::FileStream fileStream(filePath);
244 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, &fileStream);
245 EXPECT_TRUE(stopResult);
246
247 std::fstream inputStream(filePath, std::ios::in);
248 std::string line;
249 std::string emptySample = "\"samples\":";
250 std::string firstSample = "\"samples\":[0, ";
251 bool isFind = false;
252 while (getline(inputStream, line)) {
253 if (line.substr(0U, emptySample.size()) == emptySample) {
254 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
255 isFind = true;
256 }
257 }
258 EXPECT_TRUE(isFind);
259
260 inputStream.close();
261 inputStream.clear();
262 std::remove(filePath.c_str());
263 vm_->SetEnableForceGC(true);
264 }
265
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_RuntimeStat)266 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_RuntimeStat)
267 {
268 EcmaRuntimeStat *ecmaRuntimeStat = vm_->GetRuntimeStat();
269 EXPECT_TRUE(ecmaRuntimeStat != nullptr);
270
271 ecmaRuntimeStat->SetRuntimeStatEnabled(false);
272 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
273
274 DFXJSNApi::StartRuntimeStat(vm_);
275 EXPECT_TRUE(ecmaRuntimeStat->IsRuntimeStatEnabled());
276
277 DFXJSNApi::StopRuntimeStat(vm_);
278 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
279 }
280
HWTEST_F_L0(DFXJSNApiTests,GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)281 HWTEST_F_L0(DFXJSNApiTests, GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)
282 {
283 size_t arrayBufferSize = DFXJSNApi::GetArrayBufferSize(vm_);
284 size_t heapTotalSize = DFXJSNApi::GetHeapTotalSize(vm_);
285 size_t heapUsedSize = DFXJSNApi::GetHeapUsedSize(vm_);
286 size_t heapObjectSize = DFXJSNApi::GetHeapObjectSize(vm_);
287 size_t processHeapLimitSize = DFXJSNApi::GetProcessHeapLimitSize();
288
289 size_t expectArrayBufferSize = 0;
290 size_t expectHeapTotalSize = 0;
291 size_t expectHeapUsedSize = 0;
292 size_t expectHeapObjectSize = 0;
293 size_t expectProcessHeapLimitSize = 0;
294
295 if (g_isEnableCMCGC) {
296 expectHeapTotalSize = common::Heap::GetHeap().GetCurrentCapacity();
297 expectHeapUsedSize = common::Heap::GetHeap().GetSurvivedSize();
298 expectHeapObjectSize = common::Heap::GetHeap().GetAllocatedSize();
299 expectProcessHeapLimitSize = common::Heap::GetHeap().GetMaxCapacity();
300 } else {
301 auto heap = vm_->GetHeap();
302 expectArrayBufferSize = heap->GetArrayBufferSize();
303 expectHeapTotalSize = heap->GetCommittedSize();
304 expectHeapUsedSize = heap->GetLiveObjectSize();
305 expectHeapObjectSize = heap->GetHeapObjectSize();
306 expectProcessHeapLimitSize = heap->GetEcmaParamConfiguration().GetMaxHeapSize();
307 EXPECT_EQ(arrayBufferSize, expectArrayBufferSize);
308 EXPECT_LE(processHeapLimitSize, MAX_MEM_POOL_CAPACITY);
309 }
310
311 EXPECT_GE(arrayBufferSize, 0);
312 EXPECT_EQ(heapTotalSize, expectHeapTotalSize);
313 EXPECT_EQ(heapUsedSize, expectHeapUsedSize);
314 EXPECT_EQ(heapObjectSize, expectHeapObjectSize);
315 EXPECT_GE(processHeapLimitSize, expectProcessHeapLimitSize);
316 }
317
HWTEST_F_L0(DFXJSNApiTests,DFXJSNApiForGCInfo)318 HWTEST_F_L0(DFXJSNApiTests, DFXJSNApiForGCInfo)
319 {
320 if (g_isEnableCMCGC) {
321 return;
322 }
323 size_t oldGCCount = DFXJSNApi::GetGCCount(vm_);
324 size_t expectGCCount = vm_->GetEcmaGCStats()->GetGCCount() +
325 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount();
326 EXPECT_EQ(oldGCCount, expectGCCount);
327
328 size_t oldGCDuration = DFXJSNApi::GetGCDuration(vm_);
329 size_t expectGCDuration = vm_->GetEcmaGCStats()->GetGCDuration() +
330 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration();
331 EXPECT_EQ(oldGCDuration, expectGCDuration);
332
333 size_t oldAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
334 size_t expectAllocateSize = vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
335 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize();
336 EXPECT_EQ(oldAllocateSize, expectAllocateSize);
337
338 size_t oldFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
339 size_t expectFreeSize = vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
340 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize();
341 EXPECT_EQ(oldFreeSize, expectFreeSize);
342
343 size_t oldLongTimeCount = DFXJSNApi::GetFullGCLongTimeCount(vm_);
344 size_t expectLongTimeCount = vm_->GetEcmaGCStats()->GetFullGCLongTimeCount() +
345 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetFullGCLongTimeCount();
346 EXPECT_EQ(oldLongTimeCount, expectLongTimeCount);
347
348 ObjectFactory *factory = vm_->GetFactory();
349 auto heap = const_cast<Heap *>(vm_->GetHeap());
350 heap->CollectGarbage(TriggerGCType::FULL_GC);
351 {
352 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread_);
353 for (int i = 0; i < 10240; i++) {
354 factory->NewTaggedArray(512, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
355 }
356 size_t newAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
357 EXPECT_TRUE(oldAllocateSize < newAllocateSize);
358 }
359 ecmascript::SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
360 heap->CollectGarbage(TriggerGCType::FULL_GC);
361 size_t newFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
362 EXPECT_TRUE(oldFreeSize < newFreeSize);
363 size_t newGCCount = DFXJSNApi::GetGCCount(vm_);
364 EXPECT_TRUE(oldGCCount < newGCCount);
365 size_t newGCDuration = DFXJSNApi::GetGCDuration(vm_);
366 EXPECT_TRUE(oldGCDuration < newGCDuration);
367 }
368
HWTEST_F_L0(DFXJSNApiTests,NotifyApplicationState)369 HWTEST_F_L0(DFXJSNApiTests, NotifyApplicationState)
370 {
371 auto heap = vm_->GetHeap();
372 [[maybe_unused]] auto concurrentMarker = heap->GetConcurrentMarker();
373 auto sweeper = heap->GetSweeper();
374
375 DFXJSNApi::NotifyApplicationState(vm_, false);
376 #if !ECMASCRIPT_DISABLE_CONCURRENT_MARKING
377 EXPECT_TRUE(!concurrentMarker->IsDisabled());
378 #endif
379 EXPECT_TRUE(!sweeper->IsDisabled());
380
381 const_cast<ecmascript::Heap *>(heap)->CollectGarbage(TriggerGCType::OLD_GC, GCReason::OTHER);
382 DFXJSNApi::NotifyApplicationState(vm_, true);
383 #if !ECMASCRIPT_DISABLE_CONCURRENT_MARKING
384 EXPECT_TRUE(!concurrentMarker->IsDisabled());
385 #endif
386 EXPECT_TRUE(!sweeper->IsDisabled());
387 }
388
HWTEST_F_L0(DFXJSNApiTests,NotifyMemoryPressure)389 HWTEST_F_L0(DFXJSNApiTests, NotifyMemoryPressure)
390 {
391 auto heap = vm_->GetHeap();
392 bool inHighMemoryPressure = true;
393 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
394 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::PRESSURE);
395
396 inHighMemoryPressure = false;
397 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
398 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::CONSERVATIVE);
399 }
400
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList)401 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList)
402 {
403 uint32_t hostTid = vm_->GetJSThread()->GetThreadId();
404 std::vector<ecmascript::JsFrameInfo> jsFrameInfo;
405 bool result = DFXJSNApi::BuildJsStackInfoList(vm_, hostTid, jsFrameInfo);
406 EXPECT_FALSE(result);
407 }
408
HWTEST_F_L0(DFXJSNApiTests,StartSampling)409 HWTEST_F_L0(DFXJSNApiTests, StartSampling)
410 {
411 uint64_t samplingInterval = 32768;
412 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
413 EXPECT_TRUE(result);
414 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
415 EXPECT_FALSE(result);
416 }
417
HWTEST_F_L0(DFXJSNApiTests,StopSampling)418 HWTEST_F_L0(DFXJSNApiTests, StopSampling)
419 {
420 uint64_t samplingInterval = 32768;
421 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
422 EXPECT_TRUE(result);
423 DFXJSNApi::StopSampling(vm_);
424 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
425 EXPECT_TRUE(result);
426 }
427
HWTEST_F_L0(DFXJSNApiTests,GetAllocationProfile)428 HWTEST_F_L0(DFXJSNApiTests, GetAllocationProfile)
429 {
430 const SamplingInfo *result = DFXJSNApi::GetAllocationProfile(vm_);
431 EXPECT_TRUE(result == nullptr);
432 uint64_t samplingInterval = 32768;
433 DFXJSNApi::StartSampling(vm_, samplingInterval);
434 result = DFXJSNApi::GetAllocationProfile(vm_);
435 EXPECT_TRUE(result != nullptr);
436 }
437
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleStatusControl)438 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleStatusControl)
439 {
440 bool receivedValue = false;
441 std::function<void(bool)> cb = [&](bool value) {
442 receivedValue = value;
443 };
444 DFXJSNApi::NotifyIdleStatusControl(vm_, cb);
445 const_cast<ecmascript::Heap *>(vm_->GetHeap())->DisableNotifyIdle();
446 EXPECT_TRUE(receivedValue);
447 }
448
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleTime)449 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleTime)
450 {
451 if (g_isEnableCMCGC) {
452 return;
453 }
454 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
455 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
456 DFXJSNApi::NotifyIdleTime(vm_, 10);
457 EXPECT_EQ(vm_->GetEcmaGCStats()->GetGCReason(), GCReason::IDLE);
458 }
459
HWTEST_F_L0(DFXJSNApiTests,NotifyHighSensitive)460 HWTEST_F_L0(DFXJSNApiTests, NotifyHighSensitive)
461 {
462 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
463 DFXJSNApi::NotifyHighSensitive(vm_, true);
464 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
465 DFXJSNApi::NotifyHighSensitive(vm_, false);
466 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::EXIT_HIGH_SENSITIVE);
467 }
468
HWTEST_F_L0(DFXJSNApiTests,GetGCCount)469 HWTEST_F_L0(DFXJSNApiTests, GetGCCount)
470 {
471 vm_->GetJSOptions().SetIsWorker(true);
472 size_t count = DFXJSNApi::GetGCCount(vm_);
473 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount());
474
475 vm_->GetJSOptions().SetIsWorker(false);
476 count = DFXJSNApi::GetGCCount(vm_);
477 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount() +
478 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount());
479 }
480
HWTEST_F_L0(DFXJSNApiTests,GetGCDuration)481 HWTEST_F_L0(DFXJSNApiTests, GetGCDuration)
482 {
483 vm_->GetJSOptions().SetIsWorker(true);
484 size_t duration = DFXJSNApi::GetGCDuration(vm_);
485 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration());
486
487 vm_->GetJSOptions().SetIsWorker(false);
488 duration = DFXJSNApi::GetGCDuration(vm_);
489 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration() +
490 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration());
491 }
492
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedAllocateSize)493 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedAllocateSize)
494 {
495 if (g_isEnableCMCGC) {
496 size_t size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
497 ASSERT_EQ(size, common::Heap::GetHeap().GetAccumulatedAllocateSize());
498 return;
499 }
500 vm_->GetJSOptions().SetIsWorker(true);
501 size_t size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
502 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize());
503
504 vm_->GetJSOptions().SetIsWorker(false);
505 size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
506 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
507 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize());
508 }
509
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedFreeSize)510 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedFreeSize)
511 {
512 if (g_isEnableCMCGC) {
513 size_t size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
514 ASSERT_EQ(size, common::Heap::GetHeap().GetAccumulatedFreeSize());
515 return;
516 }
517 vm_->GetJSOptions().SetIsWorker(true);
518 size_t size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
519 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize());
520
521 vm_->GetJSOptions().SetIsWorker(false);
522 size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
523 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
524 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize());
525 }
526
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForColdStart)527 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForColdStart)
528 {
529 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
530 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
531
532 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_MAIN_THREAD);
533 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
534
535 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_WORKER_THREAD);
536 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
537 #else
538 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
539 #endif
540 }
541
HWTEST_F_L0(DFXJSNApiTests,CpuProfilerSamplingAnyTime)542 HWTEST_F_L0(DFXJSNApiTests, CpuProfilerSamplingAnyTime)
543 {
544 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
545 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
546 #else
547 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
548 #endif
549 }
550
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForFile)551 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForFile)
552 {
553 int interval = 32768;
554 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
555 int illegalInterval = 0;
556 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", illegalInterval));
557
558 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(nullptr, "StartCpuProfilerForFile", interval));
559
560 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
561 #else
562 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
563 #endif
564 }
565
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForInfo)566 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForInfo)
567 {
568 int interval = 32768;
569 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
570 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(nullptr, interval));
571
572 int illegalInterval = 0;
573 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, illegalInterval));
574
575 ASSERT_TRUE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
576 ASSERT_NE(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
577 #else
578 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
579 #endif
580 }
581
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForInfo)582 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForInfo)
583 {
584 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
585 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(nullptr), nullptr);
586
587 vm_->SetProfiler(nullptr);
588 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
589 #else
590 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
591 #endif
592 }
593
HWTEST_F_L0(DFXJSNApiTests,SuspendVM)594 HWTEST_F_L0(DFXJSNApiTests, SuspendVM)
595 {
596 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
597 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
598 #else
599 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
600 #endif
601 }
602
HWTEST_F_L0(DFXJSNApiTests,IsSuspended)603 HWTEST_F_L0(DFXJSNApiTests, IsSuspended)
604 {
605 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
606 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
607 #else
608 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
609 #endif
610 }
611
HWTEST_F_L0(DFXJSNApiTests,CheckSafepoint)612 HWTEST_F_L0(DFXJSNApiTests, CheckSafepoint)
613 {
614 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
615 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
616 #else
617 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
618 #endif
619 }
620
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList_2)621 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList_2)
622 {
623 std::vector<ecmascript::JsFrameInfo> jsFrames;
624 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
625 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid + 1, jsFrames));
626
627 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid, jsFrames));
628 }
629
HWTEST_F_L0(DFXJSNApiTests,StartProfiler)630 HWTEST_F_L0(DFXJSNApiTests, StartProfiler)
631 {
632 DFXJSNApi::ProfilerOption option;
633 option.profilerType = DFXJSNApi::ProfilerType::CPU_PROFILER;
634 DebuggerPostTask debuggerPostTask;
635 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
636 int32_t instanceId = 1;
637 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, true));
638
639 option.profilerType = DFXJSNApi::ProfilerType::HEAP_PROFILER;
640 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, false));
641 }
642
HWTEST_F_L0(DFXJSNApiTests,SuspendVMById)643 HWTEST_F_L0(DFXJSNApiTests, SuspendVMById)
644 {
645 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
646 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid + 1));
647
648 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
649 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
650 #else
651 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
652 #endif
653 }
654
HWTEST_F_L0(DFXJSNApiTests,StartTracing)655 HWTEST_F_L0(DFXJSNApiTests, StartTracing)
656 {
657 std::string categories = "StartTracing";
658 #if defined(ECMASCRIPT_SUPPORT_TRACING)
659 ASSERT_FALSE(DFXJSNApi::StartTracing(nullptr, categories));
660
661 vm_->SetTracing(nullptr);
662 ASSERT_TRUE(DFXJSNApi::StartTracing(vm_, categories));
663 ASSERT_NE(DFXJSNApi::StopTracing(vm_), nullptr);
664 #else
665 ASSERT_FALSE(DFXJSNApi::StartTracing(vm_, categories));
666 #endif
667 }
668
HWTEST_F_L0(DFXJSNApiTests,StopTracing)669 HWTEST_F_L0(DFXJSNApiTests, StopTracing)
670 {
671 #if defined(ECMASCRIPT_SUPPORT_TRACING)
672 ASSERT_EQ(DFXJSNApi::StopTracing(nullptr), nullptr);
673
674 vm_->SetTracing(nullptr);
675 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
676 #else
677 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
678 #endif
679 }
680
HWTEST_F_L0(DFXJSNApiTests,TranslateJSStackInfo)681 HWTEST_F_L0(DFXJSNApiTests, TranslateJSStackInfo)
682 {
683 std::string resultUrl = "";
684 auto cb = [&resultUrl](std::string& url, int& line, int& column, std::string& packageName) -> bool {
685 line = 0;
686 column = 0;
687 packageName = "name";
688 if (url.find("TranslateJSStackInfo", 0) != std::string::npos) {
689 resultUrl = "true";
690 return true;
691 }
692 resultUrl = "false";
693 return false;
694 };
695
696 vm_->SetSourceMapTranslateCallback(nullptr);
697 std::string url = "TranslateJSStackInfo";
698 int32_t line = 0;
699 int32_t column = 0;
700 std::string packageName = "";
701 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
702
703 vm_->SetSourceMapTranslateCallback(cb);
704 url = "Translate";
705 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
706 ASSERT_STREQ(resultUrl.c_str(), "false");
707
708 url = "TranslateJSStackInfo";
709 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column, packageName);
710 ASSERT_STREQ(resultUrl.c_str(), "true");
711 }
712
HWTEST_F_L0(DFXJSNApiTests,GetCurrentThreadId)713 HWTEST_F_L0(DFXJSNApiTests, GetCurrentThreadId)
714 {
715 ASSERT_EQ(DFXJSNApi::GetCurrentThreadId(), JSThread::GetCurrentThreadId());
716 }
717
FunctionCallback(JsiRuntimeCallInfo * info)718 Local<JSValueRef> FunctionCallback(JsiRuntimeCallInfo *info)
719 {
720 EscapeLocalScope scope(info->GetVM());
721 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
722 }
723
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_1)724 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_1)
725 {
726 LocalScope scope(vm_);
727 Local<FunctionRef> functioncallback = FunctionRef::New(vm_, FunctionCallback);
728 struct Data {
729 int32_t length;
730 };
731 const int32_t length = 15;
732 Data *data = new Data();
733 data->length = length;
734 functioncallback->SetData(vm_, data);
735 auto hash = DFXJSNApi::GetObjectHashCode(vm_, functioncallback);
736 ASSERT_TRUE(hash != 0);
737 }
738
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_2)739 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_2)
740 {
741 Local<ObjectRef> object = ObjectRef::New(vm_);
742 object->SetNativePointerFieldCount(vm_, 10);
743 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
744 ASSERT_TRUE(hash != 0);
745 }
746
HWTEST_F_L0(DFXJSNApiTests,GetObjectHash_3)747 HWTEST_F_L0(DFXJSNApiTests, GetObjectHash_3)
748 {
749 Local<ObjectRef> object = ObjectRef::New(vm_);
750 auto hash = DFXJSNApi::GetObjectHash(vm_, object);
751 ASSERT_TRUE(hash != 0);
752 }
753
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_3)754 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_3)
755 {
756 Local<ObjectRef> object = ObjectRef::New(vm_);
757 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
758 ASSERT_TRUE(hash != 0);
759 }
760
HWTEST_F_L0(DFXJSNApiTests,GetObjectHash_4)761 HWTEST_F_L0(DFXJSNApiTests, GetObjectHash_4)
762 {
763 Local<ObjectRef> object = ObjectRef::New(vm_);
764 NativePointerCallback callBack = nullptr;
765 void *vp1 = static_cast<void *>(new std::string("test"));
766 void *vp2 = static_cast<void *>(new std::string("test"));
767 object->SetNativePointerField(vm_, 33, vp1, callBack, vp2);
768 auto hash = DFXJSNApi::GetObjectHash(vm_, object);
769 ASSERT_TRUE(hash != 0);
770 }
771
HWTEST_F_L0(DFXJSNApiTests,GetObjectHashCode_4)772 HWTEST_F_L0(DFXJSNApiTests, GetObjectHashCode_4)
773 {
774 Local<ObjectRef> object = ObjectRef::New(vm_);
775 NativePointerCallback callBack = nullptr;
776 void *vp1 = static_cast<void *>(new std::string("test"));
777 void *vp2 = static_cast<void *>(new std::string("test"));
778 object->SetNativePointerField(vm_, 33, vp1, callBack, vp2);
779 auto hash = DFXJSNApi::GetObjectHashCode(vm_, object);
780 ASSERT_TRUE(hash != 0);
781 }
782
HWTEST_F_L0(DFXJSNApiTests,GetMainThreadStackTrace_1)783 HWTEST_F_L0(DFXJSNApiTests, GetMainThreadStackTrace_1)
784 {
785 std::string stackTraceStr;
786 DFXJSNApi::GetMainThreadStackTrace(vm_, stackTraceStr);
787 ASSERT_TRUE(stackTraceStr.empty());
788 }
789
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_1)790 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_1)
791 {
792 std::string baseFileName = ABC_PATH "module_export.abc";
793 JSNApi::EnableUserUncaughtErrorHandler(vm_);
794 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
795 EXPECT_TRUE(result);
796 std::string recordName = "module";
797 std::string namespaceName = "TestNamespace2";
798 std::string className = "TestClass1";
799 std::string funcName = "testFunction";
800 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
801 namespaceName, className, funcName);
802 EXPECT_TRUE(functionFound->IsUndefined());
803 }
804
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_2)805 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_2)
806 {
807 std::string baseFileName = ABC_PATH "module_export.abc";
808 JSNApi::EnableUserUncaughtErrorHandler(vm_);
809 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
810 EXPECT_TRUE(result);
811 std::string recordName = "module_export";
812 std::string namespaceName = "TestNamespace2";
813 std::string className = "TestClass1";
814 std::string funcName = "testFunction1";
815 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
816 namespaceName, className, funcName);
817 EXPECT_TRUE(functionFound->IsUndefined());
818 }
819
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_3)820 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_3)
821 {
822 std::string baseFileName = ABC_PATH "module_export.abc";
823 JSNApi::EnableUserUncaughtErrorHandler(vm_);
824 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
825 EXPECT_TRUE(result);
826 std::string recordName = "module_export";
827 std::string namespaceName = "TestNamespace2";
828 std::string className = "TestClass2";
829 std::string funcName = "testFunction";
830 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
831 namespaceName, className, funcName);
832 EXPECT_TRUE(functionFound->IsUndefined());
833 }
834
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_4)835 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_4)
836 {
837 std::string baseFileName = ABC_PATH "module_export.abc";
838 JSNApi::EnableUserUncaughtErrorHandler(vm_);
839 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
840 EXPECT_TRUE(result);
841 std::string recordName = "module_export";
842 std::string namespaceName = "";
843 std::string className = "TestClass2";
844 std::string funcName = "testFunction1";
845 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
846 namespaceName, className, funcName);
847 EXPECT_TRUE(functionFound->IsUndefined());
848 }
849
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_5)850 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_5)
851 {
852 std::string baseFileName = ABC_PATH "module_export.abc";
853 JSNApi::EnableUserUncaughtErrorHandler(vm_);
854 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
855 EXPECT_TRUE(result);
856 std::string recordName = "module_export";
857 std::string namespaceName = "TestNamespace2";
858 std::string className = "";
859 std::string funcName = "testFunction";
860 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
861 namespaceName, className, funcName);
862 EXPECT_TRUE(functionFound->IsUndefined());
863 }
864
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_6)865 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_6)
866 {
867 std::string baseFileName = ABC_PATH "module_export.abc";
868 JSNApi::EnableUserUncaughtErrorHandler(vm_);
869 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
870 EXPECT_TRUE(result);
871 std::string recordName = "module_export";
872 std::string namespaceName = "TestNamespace1";
873 std::string className = "";
874 std::string funcName = "testFunction";
875 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
876 namespaceName, className, funcName);
877 EXPECT_TRUE(functionFound->IsJSFunction());
878 JSFunction *function = JSFunction::Cast(functionFound->GetTaggedObject());
879 Method *method = Method::Cast(function->GetMethod(thread_));
880 EXPECT_EQ("testFunction", method->ParseFunctionName(thread_));
881 }
882
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_7)883 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_7)
884 {
885 std::string baseFileName = ABC_PATH "module_export.abc";
886 JSNApi::EnableUserUncaughtErrorHandler(vm_);
887 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
888 EXPECT_TRUE(result);
889 std::string recordName = "module_export";
890 std::string namespaceName = "TestNamespace2";
891 std::string className = "TestClass1";
892 std::string funcName = "testFunction";
893 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
894 namespaceName, className, funcName);
895 EXPECT_TRUE(functionFound->IsJSFunction());
896 JSFunction *function = JSFunction::Cast(functionFound->GetTaggedObject());
897 Method *method = Method::Cast(function->GetMethod(thread_));
898 EXPECT_EQ("testFunction", method->ParseFunctionName(thread_));
899 }
900
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_8)901 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_8)
902 {
903 std::string baseFileName = ABC_PATH "module_export.abc";
904 JSNApi::EnableUserUncaughtErrorHandler(vm_);
905 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
906 EXPECT_TRUE(result);
907 std::string recordName = "module_export";
908 std::string namespaceName = "";
909 std::string className = "TestClass2";
910 std::string funcName = "testFunction";
911 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
912 namespaceName, className, funcName);
913 EXPECT_TRUE(functionFound->IsJSFunction());
914 JSFunction *function = JSFunction::Cast(functionFound->GetTaggedObject());
915 Method *method = Method::Cast(function->GetMethod(thread_));
916 EXPECT_EQ("testFunction", method->ParseFunctionName(thread_));
917 }
918
HWTEST_F_L0(DFXJSNApiTests,FindFunctionForHook_9)919 HWTEST_F_L0(DFXJSNApiTests, FindFunctionForHook_9)
920 {
921 std::string baseFileName = ABC_PATH "module_export.abc";
922 JSNApi::EnableUserUncaughtErrorHandler(vm_);
923 bool result = JSNApi::Execute(vm_, baseFileName, "module_export");
924 EXPECT_TRUE(result);
925 std::string recordName = "module_export";
926 std::string namespaceName = "";
927 std::string className = "";
928 std::string funcName = "testFunction";
929 JSHandle<JSTaggedValue> functionFound = DFXJSNApi::FindFunctionForHook(vm_, recordName,
930 namespaceName, className, funcName);
931 EXPECT_TRUE(functionFound->IsJSFunction());
932 JSFunction *function = JSFunction::Cast(functionFound->GetTaggedObject());
933 Method *method = Method::Cast(function->GetMethod(thread_));
934 EXPECT_EQ("testFunction", method->ParseFunctionName(thread_));
935 }
936
TestForFunction1(EcmaRuntimeCallInfo * argv)937 static JSTaggedValue TestForFunction1([[maybe_unused]] EcmaRuntimeCallInfo *argv)
938 {
939 return JSTaggedValue::True();
940 }
941
TestForFunction2(EcmaRuntimeCallInfo * argv)942 static JSTaggedValue TestForFunction2([[maybe_unused]] EcmaRuntimeCallInfo *argv)
943 {
944 return JSTaggedValue::False();
945 }
946
TestForFunction3(EcmaRuntimeCallInfo * argv)947 static JSTaggedValue TestForFunction3([[maybe_unused]] EcmaRuntimeCallInfo *argv)
948 {
949 return JSTaggedValue::False();
950 }
951
HWTEST_F_L0(DFXJSNApiTests,ReplaceFunctionForHook_1)952 HWTEST_F_L0(DFXJSNApiTests, ReplaceFunctionForHook_1) {
953 LocalScope scope(vm_);
954 vm_->SetEnableForceGC(false);
955 ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
956 JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv();
957 JSHandle<JSFunction> targetFunction = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForFunction1));
958 JSHandle<LexicalEnv> lexicalEnv1 = thread_->GetEcmaVM()->GetFactory()->NewLexicalEnv(0);
959 targetFunction->SetLexicalEnv(thread_, lexicalEnv1.GetTaggedValue());
960 JSHandle<JSFunction> hookFunction = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForFunction2));
961 JSHandle<LexicalEnv> lexicalEnv2 = thread_->GetEcmaVM()->GetFactory()->NewLexicalEnv(1);
962 hookFunction->SetLexicalEnv(thread_, lexicalEnv2.GetTaggedValue());
963 JSHandle<JSFunction> backupFunction = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForFunction3));
964 JSHandle<LexicalEnv> lexicalEnv3 = thread_->GetEcmaVM()->GetFactory()->NewLexicalEnv(2);
965 backupFunction->SetLexicalEnv(thread_, lexicalEnv3.GetTaggedValue());
966 EXPECT_FALSE(targetFunction->GetLexicalEnv(thread_) == hookFunction->GetLexicalEnv(thread_));
967 EXPECT_FALSE(targetFunction->GetCodeEntryOrNativePointer() == hookFunction->GetCodeEntryOrNativePointer());
968 JSHandle<JSTaggedValue> target = JSHandle<JSTaggedValue>(targetFunction);
969 JSHandle<JSTaggedValue> hook = JSHandle<JSTaggedValue>(hookFunction);
970 JSHandle<JSTaggedValue> backup = JSHandle<JSTaggedValue>(backupFunction);
971 DFXJSNApi::ReplaceFunctionForHook(vm_, target, hook, backup);
972 JSHandle<JSFunction> targetFunc = JSHandle<JSFunction>::Cast(target);
973 JSHandle<JSFunction> hookFunc = JSHandle<JSFunction>::Cast(hook);
974 EXPECT_TRUE(targetFunc->GetLexicalEnv(thread_) == targetFunc->GetLexicalEnv(thread_));
975 EXPECT_TRUE(hookFunc->GetCodeEntryOrNativePointer() == hookFunc->GetCodeEntryOrNativePointer());
976 }
977
HWTEST_F_L0(DFXJSNApiTests,LoadHookModule_1)978 HWTEST_F_L0(DFXJSNApiTests, LoadHookModule_1)
979 {
980 LocalScope scope(vm_);
981 EXPECT_FALSE(DFXJSNApi::LoadHookModule(vm_));
982 }
983 } // namespace panda::test
984