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/ecma_context.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 class DFXJSNApiTests : public testing::Test {
33 public:
SetUpTestCase()34 static void SetUpTestCase()
35 {
36 GTEST_LOG_(INFO) << "SetUpTestCase";
37 }
38
TearDownTestCase()39 static void TearDownTestCase()
40 {
41 GTEST_LOG_(INFO) << "TearDownCase";
42 }
43
SetUp()44 void SetUp() override
45 {
46 TestHelper::CreateEcmaVMWithScope(vm_, thread_, scope_);
47 vm_->GetJSThread()->GetCurrentEcmaContext()->SetRuntimeStatEnable(true);
48 vm_->SetEnableForceGC(false);
49 }
50
TearDown()51 void TearDown() override
52 {
53 TestHelper::DestroyEcmaVMWithScope(vm_, scope_);
54 }
55
56 protected:
57 EcmaVM *vm_ {nullptr};
58 JSThread *thread_ = {nullptr};
59 EcmaHandleScope *scope_ {nullptr};
60 };
61
MatchJSONLineHeader(std::fstream & fs,const std::string filePath,int lineNum,CString lineContent)62 bool MatchJSONLineHeader(std::fstream &fs, const std::string filePath, int lineNum, CString lineContent)
63 {
64 CString tempLineContent = "";
65 int lineCount = 1;
66 fs.open(filePath.c_str(), std::ios::in);
67 while (getline(fs, tempLineContent)) {
68 if (lineNum == lineCount && tempLineContent.find(lineContent) != CString::npos) {
69 fs.close();
70 fs.clear();
71 return true;
72 }
73 lineCount++;
74 }
75 fs.close();
76 fs.clear();
77 return false;
78 }
79
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_001)80 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_001)
81 {
82 const std::string filePath = "DFXJSNApiTests_json_001.heapsnapshot";
83 std::fstream outputString(filePath, std::ios::out);
84 outputString.close();
85 outputString.clear();
86
87 std::fstream inputFile {};
88 EXPECT_TRUE(inputFile.good());
89
90 DumpSnapShotOption dumpOption;
91 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
92 dumpOption.isVmMode = true;
93 dumpOption.isPrivate = false;
94 dumpOption.captureNumericValue = false;
95 DFXJSNApi::DumpHeapSnapshot(vm_, filePath, dumpOption);
96 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 1, "{\"snapshot\":"));
97 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 2, "{\"meta\":"));
98 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 3, "{\"node_fields\":"));
99 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 4, "\"node_types\":"));
100 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 5, "\"edge_fields\":"));
101 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 6, "\"edge_types\":"));
102 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 7, "\"trace_function_info_fields\":"));
103 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 8, "\"trace_node_fields\":"));
104 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 9, "\"sample_fields\":"));
105 EXPECT_TRUE(MatchJSONLineHeader(inputFile, filePath, 10, "\"location_fields\":"));
106 std::remove(filePath.c_str());
107 }
108
HWTEST_F_L0(DFXJSNApiTests,DumpHeapSnapshot_002)109 HWTEST_F_L0(DFXJSNApiTests, DumpHeapSnapshot_002)
110 {
111 const std::string filePath = "DFXJSNApiTests_json_002.heapsnapshot";
112 std::fstream outputString(filePath, std::ios::out);
113 outputString.close();
114 outputString.clear();
115
116 ecmascript::FileStream stream(filePath);
117 EXPECT_TRUE(stream.Good());
118
119 ecmascript::Progress *progress = nullptr;
120 std::fstream fStream {};
121 EXPECT_TRUE(fStream.good());
122
123 DumpSnapShotOption dumpOption;
124 dumpOption.dumpFormat = ecmascript::DumpFormat::JSON;
125 dumpOption.isVmMode = true;
126 dumpOption.isPrivate = false;
127 dumpOption.captureNumericValue = false;
128 DFXJSNApi::DumpHeapSnapshot(vm_, &stream, dumpOption, progress);
129 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 1, "{\"snapshot\":"));
130 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 2, "{\"meta\":"));
131 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 3, "{\"node_fields\":"));
132 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 4, "\"node_types\":"));
133 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 5, "\"edge_fields\":"));
134 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 6, "\"edge_types\":"));
135 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 7, "\"trace_function_info_fields\":"));
136 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 8, "\"trace_node_fields\":"));
137 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 9, "\"sample_fields\":"));
138 EXPECT_TRUE(MatchJSONLineHeader(fStream, filePath, 10, "\"location_fields\":"));
139 std::remove(filePath.c_str());
140 }
141
HWTEST_F_L0(DFXJSNApiTests,BuildNativeAndJsStackTrace)142 HWTEST_F_L0(DFXJSNApiTests, BuildNativeAndJsStackTrace)
143 {
144 bool result = false;
145 std::string stackTraceStr = "stack_trace_str";
146 result = DFXJSNApi::BuildNativeAndJsStackTrace(vm_, stackTraceStr);
147 #if defined(ENABLE_EXCEPTION_BACKTRACE)
148 EXPECT_FALSE(stackTraceStr.empty());
149 EXPECT_TRUE(result);
150 #else
151 EXPECT_TRUE(stackTraceStr.empty());
152 EXPECT_FALSE(result);
153 #endif
154 }
155
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackTrace)156 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackTrace)
157 {
158 std::string stackTraceStr = "stack_trace_str";
159 bool result = DFXJSNApi::BuildJsStackTrace(vm_, stackTraceStr);
160 #if defined(ENABLE_EXCEPTION_BACKTRACE)
161 EXPECT_FALSE(stackTraceStr.empty());
162 EXPECT_TRUE(result);
163 #else
164 EXPECT_TRUE(stackTraceStr.empty());
165 EXPECT_FALSE(result);
166 #endif
167 }
168
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_001)169 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_001)
170 {
171 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
172 vm_->SetEnableForceGC(false);
173
174 auto factory = vm_->GetFactory();
175 bool isVmMode = true;
176 bool traceAllocation = false;
177 double timeInterval = 50; // 50 : time interval 50 ms
178 ecmascript::FileStream *stream = nullptr;
179 bool startResult = false;
180 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
181 EXPECT_TRUE(startResult);
182
183 sleep(1);
184 int count = 300;
185 while (count-- > 0) {
186 JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
187 JSHandle<EcmaString> string = factory->NewFromASCII("Start_Stop_HeapTracking_001_TestString");
188 factory->NewJSString(JSHandle<JSTaggedValue>(string), undefined);
189 }
190 const std::string filePath = "Start_Stop_HeapTracking_001.heaptimeline";
191 std::fstream outputString(filePath, std::ios::out);
192 outputString.close();
193 outputString.clear();
194
195 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, filePath);
196 EXPECT_TRUE(stopResult);
197
198 std::fstream inputStream(filePath, std::ios::in);
199 std::string line;
200 std::string emptySample = "\"samples\":";
201 std::string firstSample = "\"samples\":[0, ";
202 bool isFind = false;
203 while (getline(inputStream, line)) {
204 if (line.substr(0U, emptySample.size()) == emptySample) {
205 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
206 isFind = true;
207 }
208 }
209 EXPECT_TRUE(isFind);
210
211 inputStream.close();
212 inputStream.clear();
213 std::remove(filePath.c_str());
214 vm_->SetEnableForceGC(true);
215 }
216
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_HeapTracking_002)217 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_HeapTracking_002)
218 {
219 [[maybe_unused]] EcmaHandleScope handleScope(thread_);
220 vm_->SetEnableForceGC(false);
221
222 auto factory = vm_->GetFactory();
223 bool isVmMode = true;
224 bool traceAllocation = false;
225 double timeInterval = 50; // 50 : time interval 50 ms
226 ecmascript::FileStream *stream = nullptr;
227 bool startResult = false;
228 startResult = DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode, stream, traceAllocation);
229 EXPECT_TRUE(startResult);
230
231 sleep(1);
232 int count = 300;
233 while (count-- > 0) {
234 factory->NewJSAsyncFuncObject();
235 factory->NewJSSymbol();
236 }
237 const std::string filePath = "Start_Stop_HeapTracking_002.heaptimeline";
238 std::fstream outputString(filePath, std::ios::out);
239 outputString.close();
240 outputString.clear();
241
242 ecmascript::FileStream fileStream(filePath);
243 bool stopResult = DFXJSNApi::StopHeapTracking(vm_, &fileStream);
244 EXPECT_TRUE(stopResult);
245
246 std::fstream inputStream(filePath, std::ios::in);
247 std::string line;
248 std::string emptySample = "\"samples\":";
249 std::string firstSample = "\"samples\":[0, ";
250 bool isFind = false;
251 while (getline(inputStream, line)) {
252 if (line.substr(0U, emptySample.size()) == emptySample) {
253 EXPECT_TRUE(line.substr(0, firstSample.size()) == firstSample);
254 isFind = true;
255 }
256 }
257 EXPECT_TRUE(isFind);
258
259 inputStream.close();
260 inputStream.clear();
261 std::remove(filePath.c_str());
262 vm_->SetEnableForceGC(true);
263 }
264
HWTEST_F_L0(DFXJSNApiTests,Start_Stop_RuntimeStat)265 HWTEST_F_L0(DFXJSNApiTests, Start_Stop_RuntimeStat)
266 {
267 EcmaRuntimeStat *ecmaRuntimeStat = vm_->GetJSThread()->GetCurrentEcmaContext()->GetRuntimeStat();
268 EXPECT_TRUE(ecmaRuntimeStat != nullptr);
269
270 ecmaRuntimeStat->SetRuntimeStatEnabled(false);
271 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
272
273 DFXJSNApi::StartRuntimeStat(vm_);
274 EXPECT_TRUE(ecmaRuntimeStat->IsRuntimeStatEnabled());
275
276 DFXJSNApi::StopRuntimeStat(vm_);
277 EXPECT_TRUE(!ecmaRuntimeStat->IsRuntimeStatEnabled());
278 }
279
HWTEST_F_L0(DFXJSNApiTests,GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)280 HWTEST_F_L0(DFXJSNApiTests, GetArrayBufferSize_GetHeapTotalSize_GetHeapUsedSize)
281 {
282 auto heap = vm_->GetHeap();
283 size_t arrayBufferSize = DFXJSNApi::GetArrayBufferSize(vm_);
284 size_t expectArrayBufferSize = heap->GetArrayBufferSize();
285 EXPECT_EQ(arrayBufferSize, expectArrayBufferSize);
286
287 size_t heapTotalSize = DFXJSNApi::GetHeapTotalSize(vm_);
288 size_t expectHeapTotalSize = heap->GetCommittedSize();
289 EXPECT_EQ(heapTotalSize, expectHeapTotalSize);
290
291 size_t heapUsedSize = DFXJSNApi::GetHeapUsedSize(vm_);
292 size_t expectHeapUsedSize = heap->GetLiveObjectSize();
293 EXPECT_EQ(heapUsedSize, expectHeapUsedSize);
294
295 size_t heapObjectSize = DFXJSNApi::GetHeapObjectSize(vm_);
296 size_t expectHeapObjectSize = heap->GetHeapObjectSize();
297 EXPECT_EQ(heapObjectSize, expectHeapObjectSize);
298
299 size_t processHeapLimitSize = DFXJSNApi::GetProcessHeapLimitSize();
300 EXPECT_GE(processHeapLimitSize, heap->GetEcmaParamConfiguration().GetMaxHeapSize());
301 EXPECT_LE(processHeapLimitSize, MAX_MEM_POOL_CAPACITY);
302 }
303
HWTEST_F_L0(DFXJSNApiTests,DFXJSNApiForGCInfo)304 HWTEST_F_L0(DFXJSNApiTests, DFXJSNApiForGCInfo)
305 {
306 size_t oldGCCount = DFXJSNApi::GetGCCount(vm_);
307 size_t expectGCCount = vm_->GetEcmaGCStats()->GetGCCount() +
308 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount();
309 EXPECT_EQ(oldGCCount, expectGCCount);
310
311 size_t oldGCDuration = DFXJSNApi::GetGCDuration(vm_);
312 size_t expectGCDuration = vm_->GetEcmaGCStats()->GetGCDuration() +
313 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration();
314 EXPECT_EQ(oldGCDuration, expectGCDuration);
315
316 size_t oldAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
317 size_t expectAllocateSize = vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
318 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize();
319 EXPECT_EQ(oldAllocateSize, expectAllocateSize);
320
321 size_t oldFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
322 size_t expectFreeSize = vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
323 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize();
324 EXPECT_EQ(oldFreeSize, expectFreeSize);
325
326 size_t oldLongTimeCount = DFXJSNApi::GetFullGCLongTimeCount(vm_);
327 size_t expectLongTimeCount = vm_->GetEcmaGCStats()->GetFullGCLongTimeCount() +
328 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetFullGCLongTimeCount();
329 EXPECT_EQ(oldLongTimeCount, expectLongTimeCount);
330
331 ObjectFactory *factory = vm_->GetFactory();
332 auto heap = const_cast<Heap *>(vm_->GetHeap());
333 heap->CollectGarbage(TriggerGCType::FULL_GC);
334 {
335 [[maybe_unused]] ecmascript::EcmaHandleScope baseScope(thread_);
336 for (int i = 0; i < 10240; i++) {
337 factory->NewTaggedArray(512, JSTaggedValue::Undefined(), MemSpaceType::OLD_SPACE);
338 }
339 size_t newAllocateSize = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
340 EXPECT_TRUE(oldAllocateSize < newAllocateSize);
341 }
342 ecmascript::SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_GC, GCReason::OTHER>(thread_);
343 heap->CollectGarbage(TriggerGCType::FULL_GC);
344 size_t newFreeSize = DFXJSNApi::GetAccumulatedFreeSize(vm_);
345 EXPECT_TRUE(oldFreeSize < newFreeSize);
346 size_t newGCCount = DFXJSNApi::GetGCCount(vm_);
347 EXPECT_TRUE(oldGCCount < newGCCount);
348 size_t newGCDuration = DFXJSNApi::GetGCDuration(vm_);
349 EXPECT_TRUE(oldGCDuration < newGCDuration);
350 }
351
HWTEST_F_L0(DFXJSNApiTests,NotifyApplicationState)352 HWTEST_F_L0(DFXJSNApiTests, NotifyApplicationState)
353 {
354 auto heap = vm_->GetHeap();
355 auto concurrentMarker = heap->GetConcurrentMarker();
356 auto sweeper = heap->GetSweeper();
357
358 DFXJSNApi::NotifyApplicationState(vm_, false);
359 #if !ECMASCRIPT_DISABLE_CONCURRENT_MARKING
360 EXPECT_TRUE(!concurrentMarker->IsDisabled());
361 #endif
362 EXPECT_TRUE(!sweeper->IsDisabled());
363
364 const_cast<ecmascript::Heap *>(heap)->CollectGarbage(TriggerGCType::OLD_GC, GCReason::OTHER);
365 DFXJSNApi::NotifyApplicationState(vm_, true);
366 EXPECT_TRUE(concurrentMarker->IsDisabled());
367 EXPECT_TRUE(sweeper->IsRequestDisabled() || sweeper->IsDisabled());
368 }
369
HWTEST_F_L0(DFXJSNApiTests,NotifyMemoryPressure)370 HWTEST_F_L0(DFXJSNApiTests, NotifyMemoryPressure)
371 {
372 auto heap = vm_->GetHeap();
373 bool inHighMemoryPressure = true;
374 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
375 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::PRESSURE);
376
377 inHighMemoryPressure = false;
378 DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure);
379 EXPECT_EQ(heap->GetMemGrowingType(), MemGrowingType::CONSERVATIVE);
380 }
381
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList)382 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList)
383 {
384 uint32_t hostTid = vm_->GetJSThread()->GetThreadId();
385 std::vector<ecmascript::JsFrameInfo> jsFrameInfo;
386 bool result = DFXJSNApi::BuildJsStackInfoList(vm_, hostTid, jsFrameInfo);
387 EXPECT_FALSE(result);
388 }
389
HWTEST_F_L0(DFXJSNApiTests,StartSampling)390 HWTEST_F_L0(DFXJSNApiTests, StartSampling)
391 {
392 uint64_t samplingInterval = 32768;
393 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
394 EXPECT_TRUE(result);
395 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
396 EXPECT_FALSE(result);
397 }
398
HWTEST_F_L0(DFXJSNApiTests,StopSampling)399 HWTEST_F_L0(DFXJSNApiTests, StopSampling)
400 {
401 uint64_t samplingInterval = 32768;
402 bool result = DFXJSNApi::StartSampling(vm_, samplingInterval);
403 EXPECT_TRUE(result);
404 DFXJSNApi::StopSampling(vm_);
405 result = DFXJSNApi::StartSampling(vm_, samplingInterval);
406 EXPECT_TRUE(result);
407 }
408
HWTEST_F_L0(DFXJSNApiTests,GetAllocationProfile)409 HWTEST_F_L0(DFXJSNApiTests, GetAllocationProfile)
410 {
411 const SamplingInfo *result = DFXJSNApi::GetAllocationProfile(vm_);
412 EXPECT_TRUE(result == nullptr);
413 uint64_t samplingInterval = 32768;
414 DFXJSNApi::StartSampling(vm_, samplingInterval);
415 result = DFXJSNApi::GetAllocationProfile(vm_);
416 EXPECT_TRUE(result != nullptr);
417 }
418
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleStatusControl)419 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleStatusControl)
420 {
421 bool receivedValue = false;
422 std::function<void(bool)> cb = [&](bool value) {
423 receivedValue = value;
424 };
425 DFXJSNApi::NotifyIdleStatusControl(vm_, cb);
426 const_cast<ecmascript::Heap *>(vm_->GetHeap())->DisableNotifyIdle();
427 EXPECT_TRUE(receivedValue);
428 }
429
HWTEST_F_L0(DFXJSNApiTests,NotifyIdleTime)430 HWTEST_F_L0(DFXJSNApiTests, NotifyIdleTime)
431 {
432 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
433 heap->SetIdleTask(IdleTaskType::YOUNG_GC);
434 DFXJSNApi::NotifyIdleTime(vm_, 10);
435 EXPECT_EQ(vm_->GetEcmaGCStats()->GetGCReason(), GCReason::IDLE);
436 }
437
HWTEST_F_L0(DFXJSNApiTests,NotifyHighSensitive)438 HWTEST_F_L0(DFXJSNApiTests, NotifyHighSensitive)
439 {
440 auto heap = const_cast<ecmascript::Heap *>(vm_->GetHeap());
441 DFXJSNApi::NotifyHighSensitive(vm_, true);
442 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::ENTER_HIGH_SENSITIVE);
443 DFXJSNApi::NotifyHighSensitive(vm_, false);
444 EXPECT_TRUE(heap->GetSensitiveStatus() == AppSensitiveStatus::EXIT_HIGH_SENSITIVE);
445 }
446
HWTEST_F_L0(DFXJSNApiTests,GetGCCount)447 HWTEST_F_L0(DFXJSNApiTests, GetGCCount)
448 {
449 vm_->GetJSOptions().SetIsWorker(true);
450 size_t count = DFXJSNApi::GetGCCount(vm_);
451 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount());
452
453 vm_->GetJSOptions().SetIsWorker(false);
454 count = DFXJSNApi::GetGCCount(vm_);
455 ASSERT_EQ(count, vm_->GetEcmaGCStats()->GetGCCount() +
456 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCCount());
457 }
458
HWTEST_F_L0(DFXJSNApiTests,GetGCDuration)459 HWTEST_F_L0(DFXJSNApiTests, GetGCDuration)
460 {
461 vm_->GetJSOptions().SetIsWorker(true);
462 size_t duration = DFXJSNApi::GetGCDuration(vm_);
463 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration());
464
465 vm_->GetJSOptions().SetIsWorker(false);
466 duration = DFXJSNApi::GetGCDuration(vm_);
467 ASSERT_EQ(duration, vm_->GetEcmaGCStats()->GetGCDuration() +
468 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetGCDuration());
469 }
470
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedAllocateSize)471 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedAllocateSize)
472 {
473 vm_->GetJSOptions().SetIsWorker(true);
474 size_t size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
475 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize());
476
477 vm_->GetJSOptions().SetIsWorker(false);
478 size = DFXJSNApi::GetAccumulatedAllocateSize(vm_);
479 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedAllocateSize() +
480 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedAllocateSize());
481 }
482
HWTEST_F_L0(DFXJSNApiTests,GetAccumulatedFreeSize)483 HWTEST_F_L0(DFXJSNApiTests, GetAccumulatedFreeSize)
484 {
485 vm_->GetJSOptions().SetIsWorker(true);
486 size_t size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
487 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize());
488
489 vm_->GetJSOptions().SetIsWorker(false);
490 size = DFXJSNApi::GetAccumulatedFreeSize(vm_);
491 ASSERT_EQ(size, vm_->GetEcmaGCStats()->GetAccumulatedFreeSize() +
492 ecmascript::SharedHeap::GetInstance()->GetEcmaGCStats()->GetAccumulatedFreeSize());
493 }
494
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForColdStart)495 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForColdStart)
496 {
497 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
498 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
499
500 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_MAIN_THREAD);
501 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
502
503 vm_->GetJSOptions().SetArkProperties(ArkProperties::CPU_PROFILER_COLD_START_WORKER_THREAD);
504 ASSERT_TRUE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
505 #else
506 ASSERT_FALSE(DFXJSNApi::StopCpuProfilerForColdStart(vm_));
507 #endif
508 }
509
HWTEST_F_L0(DFXJSNApiTests,CpuProfilerSamplingAnyTime)510 HWTEST_F_L0(DFXJSNApiTests, CpuProfilerSamplingAnyTime)
511 {
512 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
513 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
514 #else
515 ASSERT_FALSE(DFXJSNApi::CpuProfilerSamplingAnyTime(vm_));
516 #endif
517 }
518
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForFile)519 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForFile)
520 {
521 int interval = 32768;
522 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
523 int illegalInterval = 0;
524 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", illegalInterval));
525
526 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(nullptr, "StartCpuProfilerForFile", interval));
527
528 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
529 #else
530 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForFile(vm_, "StartCpuProfilerForFile", interval));
531 #endif
532 }
533
HWTEST_F_L0(DFXJSNApiTests,StartCpuProfilerForInfo)534 HWTEST_F_L0(DFXJSNApiTests, StartCpuProfilerForInfo)
535 {
536 int interval = 32768;
537 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
538 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(nullptr, interval));
539
540 int illegalInterval = 0;
541 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, illegalInterval));
542
543 ASSERT_TRUE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
544 ASSERT_NE(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
545 #else
546 ASSERT_FALSE(DFXJSNApi::StartCpuProfilerForInfo(vm_, interval));
547 #endif
548 }
549
HWTEST_F_L0(DFXJSNApiTests,StopCpuProfilerForInfo)550 HWTEST_F_L0(DFXJSNApiTests, StopCpuProfilerForInfo)
551 {
552 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
553 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(nullptr), nullptr);
554
555 vm_->SetProfiler(nullptr);
556 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
557 #else
558 ASSERT_EQ(DFXJSNApi::StopCpuProfilerForInfo(vm_), nullptr);
559 #endif
560 }
561
HWTEST_F_L0(DFXJSNApiTests,SuspendVM)562 HWTEST_F_L0(DFXJSNApiTests, SuspendVM)
563 {
564 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
565 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
566 #else
567 ASSERT_FALSE(DFXJSNApi::SuspendVM(vm_));
568 #endif
569 }
570
HWTEST_F_L0(DFXJSNApiTests,IsSuspended)571 HWTEST_F_L0(DFXJSNApiTests, IsSuspended)
572 {
573 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
574 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
575 #else
576 ASSERT_FALSE(DFXJSNApi::IsSuspended(vm_));
577 #endif
578 }
579
HWTEST_F_L0(DFXJSNApiTests,CheckSafepoint)580 HWTEST_F_L0(DFXJSNApiTests, CheckSafepoint)
581 {
582 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
583 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
584 #else
585 ASSERT_FALSE(DFXJSNApi::CheckSafepoint(vm_));
586 #endif
587 }
588
HWTEST_F_L0(DFXJSNApiTests,BuildJsStackInfoList_2)589 HWTEST_F_L0(DFXJSNApiTests, BuildJsStackInfoList_2)
590 {
591 std::vector<ecmascript::JsFrameInfo> jsFrames;
592 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
593 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid + 1, jsFrames));
594
595 ASSERT_FALSE(DFXJSNApi::BuildJsStackInfoList(vm_, tid, jsFrames));
596 }
597
HWTEST_F_L0(DFXJSNApiTests,StartProfiler)598 HWTEST_F_L0(DFXJSNApiTests, StartProfiler)
599 {
600 DFXJSNApi::ProfilerOption option;
601 option.profilerType = DFXJSNApi::ProfilerType::CPU_PROFILER;
602 DebuggerPostTask debuggerPostTask;
603 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
604 int32_t instanceId = 1;
605 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, true));
606
607 option.profilerType = DFXJSNApi::ProfilerType::HEAP_PROFILER;
608 ASSERT_FALSE(DFXJSNApi::StartProfiler(nullptr, option, tid, instanceId, debuggerPostTask, false));
609 }
610
HWTEST_F_L0(DFXJSNApiTests,SuspendVMById)611 HWTEST_F_L0(DFXJSNApiTests, SuspendVMById)
612 {
613 uint32_t tid = vm_->GetAssociatedJSThread()->GetThreadId();
614 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid + 1));
615
616 #if defined(ECMASCRIPT_SUPPORT_SNAPSHOT)
617 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
618 #else
619 ASSERT_FALSE(DFXJSNApi::SuspendVMById(vm_, tid));
620 #endif
621 }
622
HWTEST_F_L0(DFXJSNApiTests,StartTracing)623 HWTEST_F_L0(DFXJSNApiTests, StartTracing)
624 {
625 std::string categories = "StartTracing";
626 #if defined(ECMASCRIPT_SUPPORT_TRACING)
627 ASSERT_FALSE(DFXJSNApi::StartTracing(nullptr, categories));
628
629 vm_->SetTracing(nullptr);
630 ASSERT_TRUE(DFXJSNApi::StartTracing(vm_, categories));
631 ASSERT_NE(DFXJSNApi::StopTracing(vm_), nullptr);
632 #else
633 ASSERT_FALSE(DFXJSNApi::StartTracing(vm_, categories));
634 #endif
635 }
636
HWTEST_F_L0(DFXJSNApiTests,StopTracing)637 HWTEST_F_L0(DFXJSNApiTests, StopTracing)
638 {
639 #if defined(ECMASCRIPT_SUPPORT_TRACING)
640 ASSERT_EQ(DFXJSNApi::StopTracing(nullptr), nullptr);
641
642 vm_->SetTracing(nullptr);
643 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
644 #else
645 ASSERT_EQ(DFXJSNApi::StopTracing(vm_), nullptr);
646 #endif
647 }
648
HWTEST_F_L0(DFXJSNApiTests,TranslateJSStackInfo)649 HWTEST_F_L0(DFXJSNApiTests, TranslateJSStackInfo)
650 {
651 std::string resultUrl = "";
652 auto cb = [&resultUrl](std::string& url, int& line, int& column) -> bool {
653 line = 0;
654 column = 0;
655 if (url.find("TranslateJSStackInfo", 0) != std::string::npos) {
656 resultUrl = "true";
657 return true;
658 }
659 resultUrl = "false";
660 return false;
661 };
662
663 vm_->SetSourceMapTranslateCallback(nullptr);
664 std::string url = "TranslateJSStackInfo";
665 int32_t line = 0;
666 int32_t column = 0;
667 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column);
668
669 vm_->SetSourceMapTranslateCallback(cb);
670 url = "Translate";
671 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column);
672 ASSERT_STREQ(resultUrl.c_str(), "false");
673
674 url = "TranslateJSStackInfo";
675 DFXJSNApi::TranslateJSStackInfo(vm_, url, line, column);
676 ASSERT_STREQ(resultUrl.c_str(), "true");
677 }
678
HWTEST_F_L0(DFXJSNApiTests,GetCurrentThreadId)679 HWTEST_F_L0(DFXJSNApiTests, GetCurrentThreadId)
680 {
681 ASSERT_EQ(DFXJSNApi::GetCurrentThreadId(), JSThread::GetCurrentThreadId());
682 }
683 } // namespace panda::test
684