• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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