• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <cstdio>
17 
18 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
19 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
20 #include "ecmascript/tests/test_helper.h"
21 
22 using namespace panda::ecmascript;
23 
24 namespace panda::ecmascript {
25 class SamplesRecordFriendTest {
26 public:
SamplesRecordFriendTest()27     SamplesRecordFriendTest() : samples_record() {}
28 
AddRunningStateTest(char * functionName,RunningState state,kungfu::DeoptType type)29     std::string AddRunningStateTest(char *functionName, RunningState state, kungfu::DeoptType type)
30     {
31         return samples_record.AddRunningState(functionName, state, type);
32     }
33 
SetEnableVMTag(bool flag)34     void SetEnableVMTag(bool flag)
35     {
36         samples_record.SetEnableVMTag(flag);
37     }
38 
StatisticStateTimeTest(int timeDelta,RunningState state)39     void StatisticStateTimeTest(int timeDelta, RunningState state)
40     {
41         samples_record.StatisticStateTime(timeDelta, state);
42     }
43 
PushNapiStackInfoTest(const FrameInfoTemp & frameInfoTemp)44     bool PushNapiStackInfoTest(const FrameInfoTemp &frameInfoTemp)
45     {
46         return samples_record.PushNapiStackInfo(frameInfoTemp);
47     }
48 
NapiFrameInfoTempToMapTest()49     void NapiFrameInfoTempToMapTest()
50     {
51         samples_record.NapiFrameInfoTempToMap();
52     }
53 
TranslateUrlPositionBySourceMapTest(struct FrameInfo & codeEntry)54     void TranslateUrlPositionBySourceMapTest(struct FrameInfo &codeEntry)
55     {
56         samples_record.TranslateUrlPositionBySourceMap(codeEntry);
57     }
58 
sourceMapTranslateCallbackTest(SourceMapTranslateCallback sourceMapTranslateCallback_)59     void sourceMapTranslateCallbackTest(SourceMapTranslateCallback sourceMapTranslateCallback_)
60     {
61         samples_record.sourceMapTranslateCallback_ = sourceMapTranslateCallback_;
62     }
63 
GetProfileInfoTest()64     std::unique_ptr<ProfileInfo> GetProfileInfoTest()
65     {
66         return std::move(samples_record.profileInfo_);
67     }
68 
69 private:
70     SamplesRecord samples_record;
71 };
72 }
73 
74 namespace panda::test {
75 class SamplesRecordTest : public testing::Test {
76 public:
SetUpTestCase()77     static void SetUpTestCase()
78     {
79         GTEST_LOG_(INFO) << "SetUpTestCase";
80     }
81 
TearDownTestCase()82     static void TearDownTestCase()
83     {
84         GTEST_LOG_(INFO) << "TearDownCase";
85     }
86 
SetUp()87     void SetUp() override
88     {
89         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
90         instance->SetEnableForceGC(false);
91     }
92 
TearDown()93     void TearDown() override
94     {
95         TestHelper::DestroyEcmaVMWithScope(instance, scope);
96     }
97 
98     EcmaVM *instance {nullptr};
99     EcmaHandleScope *scope {nullptr};
100     JSThread *thread {nullptr};
101 };
102 
HWTEST_F_L0(SamplesRecordTest,AddRunningStateTest)103 HWTEST_F_L0(SamplesRecordTest, AddRunningStateTest)
104 {
105     SamplesRecordFriendTest samplesRecord;
106     char funcName[] = "testFunction";
107     std::string result = samplesRecord.AddRunningStateTest(funcName, RunningState::AINT_D,
108         kungfu::DeoptType::NONE);
109     EXPECT_EQ(result, "testFunction(AINT-D)");
110 
111     result = samplesRecord.AddRunningStateTest(funcName, RunningState::GC,
112         kungfu::DeoptType::NOTDOUBLE1);
113     EXPECT_EQ(result, "testFunction(GC)");
114 
115     result = samplesRecord.AddRunningStateTest(funcName, RunningState::CINT,
116         kungfu::DeoptType::NOTDOUBLE1);
117     EXPECT_EQ(result, "testFunction");
118 
119     result = samplesRecord.AddRunningStateTest(funcName, RunningState::AINT,
120         kungfu::DeoptType::NOTDOUBLE1);
121     EXPECT_EQ(result, "testFunction");
122 
123     result = samplesRecord.AddRunningStateTest(funcName, RunningState::AOT,
124         kungfu::DeoptType::NOTDOUBLE1);
125     EXPECT_EQ(result, "testFunction");
126 
127     result = samplesRecord.AddRunningStateTest(funcName, RunningState::BUILTIN,
128         kungfu::DeoptType::NOTDOUBLE1);
129     EXPECT_EQ(result, "testFunction(BUILTIN)");
130 
131     result = samplesRecord.AddRunningStateTest(funcName, RunningState::NAPI,
132         kungfu::DeoptType::NOTDOUBLE1);
133     EXPECT_EQ(result, "testFunction(NAPI)");
134 
135     result = samplesRecord.AddRunningStateTest(funcName, RunningState::ARKUI_ENGINE,
136         kungfu::DeoptType::NOTDOUBLE1);
137     EXPECT_EQ(result, "testFunction(ARKUI_ENGINE)");
138 
139     result = samplesRecord.AddRunningStateTest(funcName, RunningState::RUNTIME,
140         kungfu::DeoptType::NOTDOUBLE1);
141     EXPECT_EQ(result, "testFunction");
142 
143     result = samplesRecord.AddRunningStateTest(funcName, RunningState::JIT,
144         kungfu::DeoptType::NOTDOUBLE1);
145     EXPECT_EQ(result, "testFunction(JIT)");
146 
147     samplesRecord.SetEnableVMTag(true);
148     result = samplesRecord.AddRunningStateTest(funcName, RunningState::CINT,
149         kungfu::DeoptType::NOTDOUBLE1);
150     EXPECT_EQ(result, "testFunction(CINT)");
151 
152     result = samplesRecord.AddRunningStateTest(funcName, RunningState::AINT,
153         kungfu::DeoptType::NOTDOUBLE1);
154     EXPECT_EQ(result, "testFunction(AINT)");
155 
156     result = samplesRecord.AddRunningStateTest(funcName, RunningState::AOT,
157         kungfu::DeoptType::NOTDOUBLE1);
158     EXPECT_EQ(result, "testFunction(AOT)");
159 
160     result = samplesRecord.AddRunningStateTest(funcName, RunningState::RUNTIME,
161         kungfu::DeoptType::NOTDOUBLE1);
162     EXPECT_EQ(result, "testFunction(RUNTIME)");
163 
164     result = samplesRecord.AddRunningStateTest(funcName, RunningState::AINT_D,
165         kungfu::DeoptType::NOTINT1);
166     EXPECT_EQ(result, "testFunction(AINT-D)(DEOPT:NotInt1)");
167 }
168 
HWTEST_F_L0(SamplesRecordTest,StatisticStateTimeTest)169 HWTEST_F_L0(SamplesRecordTest, StatisticStateTimeTest)
170 {
171     SamplesRecordFriendTest samplesRecord;
172     samplesRecord.StatisticStateTimeTest(100, RunningState::AINT_D);
173     samplesRecord.StatisticStateTimeTest(101, RunningState::GC);
174     samplesRecord.StatisticStateTimeTest(102, RunningState::CINT);
175     samplesRecord.StatisticStateTimeTest(103, RunningState::AINT);
176     samplesRecord.StatisticStateTimeTest(104, RunningState::AOT);
177     samplesRecord.StatisticStateTimeTest(105, RunningState::BUILTIN);
178     samplesRecord.StatisticStateTimeTest(106, RunningState::NAPI);
179     samplesRecord.StatisticStateTimeTest(107, RunningState::ARKUI_ENGINE);
180     samplesRecord.StatisticStateTimeTest(108, RunningState::RUNTIME);
181     samplesRecord.StatisticStateTimeTest(109, RunningState::JIT);
182 
183     std::unique_ptr<ProfileInfo> profileInfo = samplesRecord.GetProfileInfoTest();
184     EXPECT_EQ(profileInfo->asmInterpreterDeoptTime, 100);
185     EXPECT_EQ(profileInfo->gcTime, 101);
186     EXPECT_EQ(profileInfo->cInterpreterTime, 102);
187     EXPECT_EQ(profileInfo->asmInterpreterTime, 103);
188     EXPECT_EQ(profileInfo->aotTime, 104);
189     EXPECT_EQ(profileInfo->builtinTime, 105);
190     EXPECT_EQ(profileInfo->napiTime, 106);
191     EXPECT_EQ(profileInfo->arkuiEngineTime, 107);
192     EXPECT_EQ(profileInfo->runtimeTime, 108);
193     EXPECT_EQ(profileInfo->jitTime, 109);
194 }
195 
HWTEST_F_L0(SamplesRecordTest,PushStackTest)196 HWTEST_F_L0(SamplesRecordTest, PushStackTest)
197 {
198     SamplesRecord record;
199     MethodKey key;
200 
201     for (size_t i = 0; i < MAX_STACK_SIZE; ++i) {
202         key.lineNumber = static_cast<int>(i);
203         EXPECT_TRUE(record.PushFrameStack(key));
204     }
205     EXPECT_FALSE(record.PushFrameStack(key));
206 
207     for (size_t i = 0; i < MAX_STACK_SIZE; ++i) {
208         key.lineNumber = static_cast<int>(i);
209         EXPECT_TRUE(record.PushNapiFrameStack(key));
210     }
211     EXPECT_FALSE(record.PushNapiFrameStack(key));
212 
213     FrameInfoTemp frameInfoTemp;
214     for (size_t i = 0; i < MAX_STACK_SIZE; ++i) {
215         frameInfoTemp.lineNumber = static_cast<int>(i);
216         EXPECT_TRUE(record.PushStackInfo(frameInfoTemp));
217     }
218     EXPECT_FALSE(record.PushStackInfo(frameInfoTemp));
219 
220     for (size_t i = 0; i < MAX_STACK_SIZE; ++i) {
221         frameInfoTemp.lineNumber = static_cast<int>(i);
222         EXPECT_TRUE(record.PushNapiStackInfo(frameInfoTemp));
223     }
224     EXPECT_FALSE(record.PushNapiStackInfo(frameInfoTemp));
225 }
226 
HWTEST_F_L0(SamplesRecordTest,GetModuleNameTest)227 HWTEST_F_L0(SamplesRecordTest, GetModuleNameTest)
228 {
229     SamplesRecord record;
230 
231     char input1[] = "/path/to/module@version";
232     EXPECT_EQ(record.GetModuleName(input1), "module");
233 
234     char input2[] = "/path/to/module";
235     EXPECT_EQ(record.GetModuleName(input2), "");
236 
237     char input3[] = "module@version";
238     EXPECT_EQ(record.GetModuleName(input3), "");
239 }
240 
HWTEST_F_L0(SamplesRecordTest,NapiFrameInfoTempToMapTest)241 HWTEST_F_L0(SamplesRecordTest, NapiFrameInfoTempToMapTest)
242 {
243     SamplesRecordFriendTest samplesRecord;
244     samplesRecord.NapiFrameInfoTempToMapTest();
245     FrameInfoTemp frameInfoTemp;
246     frameInfoTemp.lineNumber = static_cast<int>(5);
247     samplesRecord.PushNapiStackInfoTest(frameInfoTemp);
248     samplesRecord.NapiFrameInfoTempToMapTest();
249 }
250 
HWTEST_F_L0(SamplesRecordTest,TranslateUrlPositionBySourceMapTest)251 HWTEST_F_L0(SamplesRecordTest, TranslateUrlPositionBySourceMapTest)
252 {
253     SamplesRecordFriendTest samplesRecord;
254     FrameInfo entry1;
255     SourceMapTranslateCallback sourceMapTranslateCallback_ = [](const std::string&, int, int,
256                                                                 std::string) { return true; };
257     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
258     samplesRecord.TranslateUrlPositionBySourceMapTest(entry1);
259     EXPECT_EQ(entry1.url, "");
260 
261     FrameInfo entry2;
262     entry2.url = "some_url.js";
263     entry2.packageName = "name";
264     sourceMapTranslateCallback_ = [](const std::string&, int, int, std::string) { return true; };
265     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
266     samplesRecord.TranslateUrlPositionBySourceMapTest(entry2);
267     EXPECT_EQ(entry2.url, "some_url.js");
268 
269     FrameInfo entry3;
270     entry3.url = "path/to/_.js";
271     entry3.packageName = "name";
272     sourceMapTranslateCallback_ = [](const std::string&, int, int, std::string) { return false; };
273     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
274     samplesRecord.TranslateUrlPositionBySourceMapTest(entry3);
275     EXPECT_EQ(entry3.url, "path/to/_.js");
276 
277     FrameInfo entry4;
278     entry4.url = "entry/some_key.ets";
279     entry4.packageName = "name";
280     sourceMapTranslateCallback_ = [](const std::string&, int, int, std::string) { return false; };
281     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
282     samplesRecord.TranslateUrlPositionBySourceMapTest(entry4);
283     EXPECT_EQ(entry4.url, "entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/some_key.js");
284 
285     FrameInfo entry5;
286     entry5.url = "entry/some_key.other";
287     entry5.packageName = "name";
288     sourceMapTranslateCallback_ = [](const std::string&, int, int, std::string) { return false; };
289     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
290     samplesRecord.TranslateUrlPositionBySourceMapTest(entry5);
291     EXPECT_EQ(entry5.url, "entry/some_key.other");
292 
293     FrameInfo entry6;
294     entry6.url = "other/path.js";
295     entry6.packageName = "name";
296     sourceMapTranslateCallback_ = [](const std::string&, int, int, std::string) { return false; };
297     samplesRecord.sourceMapTranslateCallbackTest(sourceMapTranslateCallback_);
298     samplesRecord.TranslateUrlPositionBySourceMapTest(entry6);
299     EXPECT_EQ(entry6.url, "other/path.js");
300 }
301 }  // namespace panda::test