1/*
2 * Copyright (c) 2022 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 "agent/profiler_impl.h"
17#include "ecmascript/tests/test_helper.h"
18#include "protocol_handler.h"
19
20using namespace panda::ecmascript;
21using namespace panda::ecmascript::tooling;
22
23namespace panda::test {
24class ProfilerImplTest : public testing::Test {
25public:
26    static void SetUpTestCase()
27    {
28        GTEST_LOG_(INFO) << "SetUpTestCase";
29    }
30
31    static void TearDownTestCase()
32    {
33        GTEST_LOG_(INFO) << "TearDownCase";
34    }
35
36    void SetUp() override
37    {
38        TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
39    }
40
41    void TearDown() override
42    {
43        TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
44    }
45
46protected:
47    EcmaVM *ecmaVm {nullptr};
48    EcmaHandleScope *scope {nullptr};
49    JSThread *thread {nullptr};
50};
51
52HWTEST_F_L0(ProfilerImplTest, Disable)
53{
54    ProtocolChannel *channel = nullptr;
55    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
56    DispatchResponse response = profiler->Disable();
57    ASSERT_TRUE(response.GetMessage() == "");
58    ASSERT_TRUE(response.IsOk());
59}
60
61HWTEST_F_L0(ProfilerImplTest, Enable)
62{
63    ProtocolChannel *channel = nullptr;
64    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
65    DispatchResponse response = profiler->Enable();
66    ASSERT_TRUE(response.GetMessage() == "");
67    ASSERT_TRUE(response.IsOk());
68}
69
70
71HWTEST_F_L0(ProfilerImplTest, Start)
72{
73    ProtocolChannel *channel = nullptr;
74    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
75    DispatchResponse response = profiler->Start();
76    std::unique_ptr<Profile> profile;
77    DispatchResponse response1 = profiler->Stop(&profile);
78    ASSERT_TRUE(response.IsOk());
79    ASSERT_TRUE(response1.IsOk());
80    ASSERT_TRUE(profile);
81}
82
83HWTEST_F_L0(ProfilerImplTest, Stop)
84{
85    ProtocolChannel *channel = nullptr;
86    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
87    std::unique_ptr<Profile> profile;
88    DispatchResponse response = profiler->Stop(&profile);
89    ASSERT_TRUE(response.GetMessage().find("Stop is failure") != std::string::npos);
90    ASSERT_TRUE(!response.IsOk());
91}
92
93HWTEST_F_L0(ProfilerImplTest, SetSamplingInterval)
94{
95    ProtocolChannel *channel = nullptr;
96    SetSamplingIntervalParams params;
97    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
98    DispatchResponse response = profiler->SetSamplingInterval(params);
99    ASSERT_TRUE(response.GetMessage() == "");
100    ASSERT_TRUE(response.IsOk());
101}
102
103HWTEST_F_L0(ProfilerImplTest, EnableSerializationTimeoutCheck)
104{
105    ProtocolChannel *channel = nullptr;
106    SeriliazationTimeoutCheckEnableParams params;
107    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
108    DispatchResponse response = profiler->EnableSerializationTimeoutCheck(params);
109    ASSERT_TRUE(response.GetMessage() == "");
110    ASSERT_TRUE(response.IsOk());
111}
112
113HWTEST_F_L0(ProfilerImplTest, DisableSerializationTimeoutCheck)
114{
115    ProtocolChannel *channel = nullptr;
116    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
117    DispatchResponse response = profiler->DisableSerializationTimeoutCheck();
118    ASSERT_TRUE(response.GetMessage() == "");
119    ASSERT_TRUE(response.IsOk());
120}
121
122HWTEST_F_L0(ProfilerImplTest, GetBestEffortCoverage)
123{
124    ProtocolChannel *channel = nullptr;
125    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
126    DispatchResponse response = profiler->GetBestEffortCoverage();
127    ASSERT_TRUE(response.GetMessage() == "GetBestEffortCoverage not support now");
128}
129
130HWTEST_F_L0(ProfilerImplTest, StopPreciseCoverage)
131{
132    ProtocolChannel *channel = nullptr;
133    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
134    DispatchResponse response = profiler->StopPreciseCoverage();
135    ASSERT_TRUE(response.GetMessage() == "StopPreciseCoverage not support now");
136}
137
138HWTEST_F_L0(ProfilerImplTest, TakePreciseCoverage)
139{
140    ProtocolChannel *channel = nullptr;
141    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
142    DispatchResponse response = profiler->TakePreciseCoverage();
143    ASSERT_TRUE(response.GetMessage() == "TakePreciseCoverage not support now");
144}
145
146HWTEST_F_L0(ProfilerImplTest, StartPreciseCoverage)
147{
148    ProtocolChannel *channel = nullptr;
149    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
150    std::string msg = std::string() + R"({"id":0,"method":"Debugger.requestMemoryDump","params":{}})";
151    DispatchRequest request = DispatchRequest(msg);
152    std::unique_ptr<StartPreciseCoverageParams> params = StartPreciseCoverageParams::Create(request.GetParams());
153    DispatchResponse response = profiler->StartPreciseCoverage(*params);
154    ASSERT_TRUE(response.GetMessage() == "StartPreciseCoverage not support now");
155}
156
157HWTEST_F_L0(ProfilerImplTest, StartTypeProfile)
158{
159    ProtocolChannel *channel = nullptr;
160    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
161    DispatchResponse response = profiler->StartTypeProfile();
162    ASSERT_TRUE(response.GetMessage() == "StartTypeProfile not support now");
163}
164
165HWTEST_F_L0(ProfilerImplTest, StopTypeProfile)
166{
167    ProtocolChannel *channel = nullptr;
168    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
169    DispatchResponse response = profiler->StopTypeProfile();
170    ASSERT_TRUE(response.GetMessage() == "StopTypeProfile not support now");
171}
172
173HWTEST_F_L0(ProfilerImplTest, TakeTypeProfile)
174{
175    ProtocolChannel *channel = nullptr;
176    auto profiler = std::make_unique<ProfilerImpl>(ecmaVm, channel);
177    DispatchResponse response = profiler->TakeTypeProfile();
178    ASSERT_TRUE(response.GetMessage() == "TakeTypeProfile not support now");
179}
180
181HWTEST_F_L0(ProfilerImplTest, DispatcherImplDispatch)
182{
183    std::string result = "";
184    std::function<void(const void*, const std::string &)> callback =
185        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
186    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
187    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
188    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
189    std::string msg = std::string() + R"({"id":0,"method":"Profiler.Test","params":{}})";
190    DispatchRequest request(msg);
191    dispatcherImpl->Dispatch(request);
192    ASSERT_TRUE(result.find("Unknown method: Test") != std::string::npos);
193    msg = std::string() + R"({"id":0,"method":"Profiler.disable","params":{}})";
194    DispatchRequest request1 = DispatchRequest(msg);
195    dispatcherImpl->Dispatch(request1);
196    if (channel) {
197        delete channel;
198        channel = nullptr;
199    }
200    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
201}
202
203HWTEST_F_L0(ProfilerImplTest, DispatcherImplEnable)
204{
205    std::string result = "";
206    std::function<void(const void*, const std::string &)> callback =
207        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
208    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
209    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
210    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
211    std::string msg = std::string() + R"({"id":0,"method":"Profiler.enable","params":{}})";
212    DispatchRequest request(msg);
213    dispatcherImpl->Dispatch(request);
214    if (channel) {
215        delete channel;
216        channel = nullptr;
217    }
218    ASSERT_TRUE(result.find("protocols") != std::string::npos);
219}
220
221HWTEST_F_L0(ProfilerImplTest, DispatcherImplDisable)
222{
223    std::string result = "";
224    std::function<void(const void*, const std::string &)> callback =
225        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
226    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
227    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
228    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
229    std::string msg = std::string() + R"({"id":0,"method":"Profiler.disable","params":{}})";
230    DispatchRequest request(msg);
231    dispatcherImpl->Dispatch(request);
232    if (channel) {
233        delete channel;
234        channel = nullptr;
235    }
236    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
237}
238
239HWTEST_F_L0(ProfilerImplTest, DispatcherImplStart)
240{
241    std::string result = "";
242    std::function<void(const void*, const std::string &)> callback =
243        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
244    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
245    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
246    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
247    std::string msg = std::string() + R"({"id":0,"method":"Profiler.start","params":{}})";
248    DispatchRequest request(msg);
249    dispatcherImpl->Dispatch(request);
250    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
251    msg = std::string() + R"({"id":0,"method":"Profiler.stop","params":{}})";
252    DispatchRequest request1 = DispatchRequest(msg);
253    dispatcherImpl->Dispatch(request1);
254    if (channel) {
255        delete channel;
256        channel = nullptr;
257    }
258    ASSERT_TRUE(result.find("\"id\":0") != std::string::npos);
259    ASSERT_TRUE(result.find("\"profile\"") != std::string::npos);
260}
261
262HWTEST_F_L0(ProfilerImplTest, DispatcherImplStop)
263{
264    std::string result = "";
265    std::function<void(const void*, const std::string &)> callback =
266        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
267    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
268    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
269    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
270    std::string msg = std::string() + R"({"id":0,"method":"Profiler.stop","params":{}})";
271    DispatchRequest request(msg);
272    dispatcherImpl->Dispatch(request);
273    if (channel) {
274        delete channel;
275        channel = nullptr;
276    }
277    ASSERT_TRUE(result.find("Stop is failure") != std::string::npos);
278}
279
280HWTEST_F_L0(ProfilerImplTest, DispatcherImplSetSamplingInterval)
281{
282    std::string result = "";
283    std::function<void(const void*, const std::string &)> callback =
284        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
285    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
286    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
287    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
288    std::string msg = std::string() + R"({"id":0,"method":"Profiler.setSamplingInterval","params":{}})";
289    DispatchRequest request(msg);
290    dispatcherImpl->Dispatch(request);
291    ASSERT_TRUE(result.find("wrong params") != std::string::npos);
292    msg = std::string() + R"({"id":0,"method":"Profiler.setSamplingInterval","params":{"interval":24}})";
293    DispatchRequest request1(msg);
294    dispatcherImpl->Dispatch(request1);
295    if (channel) {
296        delete channel;
297        channel = nullptr;
298    }
299    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
300}
301
302HWTEST_F_L0(ProfilerImplTest, DispatcherImplGetBestEffortCoverage)
303{
304    std::string result = "";
305    std::function<void(const void*, const std::string &)> callback =
306        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
307    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
308    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
309    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
310    std::string msg = std::string() + R"({"id":0,"method":"Profiler.getBestEffortCoverage","params":{}})";
311    DispatchRequest request(msg);
312    dispatcherImpl->Dispatch(request);
313    if (channel) {
314        delete channel;
315        channel = nullptr;
316    }
317    ASSERT_TRUE(result.find("GetBestEffortCoverage not support now") != std::string::npos);
318}
319
320HWTEST_F_L0(ProfilerImplTest, DispatcherImplStopPreciseCoverage)
321{
322    std::string result = "";
323    std::function<void(const void*, const std::string &)> callback =
324        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
325    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
326    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
327    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
328    std::string msg = std::string() + R"({"id":0,"method":"Profiler.stopPreciseCoverage","params":{}})";
329    DispatchRequest request(msg);
330    dispatcherImpl->Dispatch(request);
331    if (channel) {
332        delete channel;
333        channel = nullptr;
334    }
335    ASSERT_TRUE(result.find("StopPreciseCoverage not support now") != std::string::npos);
336}
337
338HWTEST_F_L0(ProfilerImplTest, DispatcherImplTakePreciseCoverage)
339{
340    std::string result = "";
341    std::function<void(const void*, const std::string &)> callback =
342        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
343    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
344    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
345    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
346    std::string msg = std::string() + R"({"id":0,"method":"Profiler.takePreciseCoverage","params":{}})";
347    DispatchRequest request(msg);
348    dispatcherImpl->Dispatch(request);
349    if (channel) {
350        delete channel;
351        channel = nullptr;
352    }
353    ASSERT_TRUE(result.find("TakePreciseCoverage not support now") != std::string::npos);
354}
355
356HWTEST_F_L0(ProfilerImplTest, DispatcherImplStartPreciseCoverage)
357{
358    std::string result = "";
359    std::function<void(const void*, const std::string &)> callback =
360        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
361    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
362    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
363    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
364    std::string msg = std::string() + R"({"id":0,"method":"Profiler.startPreciseCoverage","params":{}})";
365    DispatchRequest request(msg);
366    dispatcherImpl->Dispatch(request);
367    if (channel) {
368        delete channel;
369        channel = nullptr;
370    }
371    ASSERT_TRUE(result.find("StartPreciseCoverage not support now") != std::string::npos);
372}
373
374HWTEST_F_L0(ProfilerImplTest, DispatcherImplStartTypeProfile)
375{
376    std::string result = "";
377    std::function<void(const void*, const std::string &)> callback =
378        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
379    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
380    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
381    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
382    std::string msg = std::string() + R"({"id":0,"method":"Profiler.startTypeProfile","params":{}})";
383    DispatchRequest request(msg);
384    dispatcherImpl->Dispatch(request);
385    if (channel) {
386        delete channel;
387        channel = nullptr;
388    }
389    ASSERT_TRUE(result.find("StartTypeProfile not support now") != std::string::npos);
390}
391
392HWTEST_F_L0(ProfilerImplTest, DispatcherImplStopTypeProfile)
393{
394    std::string result = "";
395    std::function<void(const void*, const std::string &)> callback =
396        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
397    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
398    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
399    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
400    std::string msg = std::string() + R"({"id":0,"method":"Profiler.stopTypeProfile","params":{}})";
401    DispatchRequest request(msg);
402    dispatcherImpl->Dispatch(request);
403    if (channel) {
404        delete channel;
405        channel = nullptr;
406    }
407    ASSERT_TRUE(result.find("StopTypeProfile not support now") != std::string::npos);
408}
409
410HWTEST_F_L0(ProfilerImplTest, DispatcherImplTakeTypeProfile)
411{
412    std::string result = "";
413    std::function<void(const void*, const std::string &)> callback =
414        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
415    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
416    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
417    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
418    std::string msg = std::string() + R"({"id":0,"method":"Profiler.takeTypeProfile","params":{}})";
419    DispatchRequest request(msg);
420    dispatcherImpl->Dispatch(request);
421    if (channel) {
422        delete channel;
423        channel = nullptr;
424    }
425    ASSERT_TRUE(result.find("TakeTypeProfile not support now") != std::string::npos);
426}
427
428HWTEST_F_L0(ProfilerImplTest, DispatcherImplDisableSerializationTimeoutCheck)
429{
430    std::string result = "";
431    std::function<void(const void*, const std::string &)> callback =
432        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
433    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
434    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
435    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
436    std::string msg = std::string() + R"({"id":0,"method":"Profiler.disableSerializationTimeoutCheck","params":{}})";
437    DispatchRequest request(msg);
438    dispatcherImpl->Dispatch(request);
439    if (channel) {
440        delete channel;
441        channel = nullptr;
442    }
443    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
444}
445
446HWTEST_F_L0(ProfilerImplTest, DispatcherImplEnableSerializationTimeoutCheck)
447{
448    std::string result = "";
449    std::function<void(const void*, const std::string &)> callback =
450        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
451    ProtocolChannel *channel = new ProtocolHandler(callback, ecmaVm);
452    auto tracing = std::make_unique<ProfilerImpl>(ecmaVm, channel);
453    auto dispatcherImpl = std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(tracing));
454    std::string msg = std::string() + R"({"id":0,"method":"Profiler.enableSerializationTimeoutCheck","params":{}})";
455    DispatchRequest request(msg);
456    dispatcherImpl->Dispatch(request);
457    ASSERT_TRUE(result.find("wrong params") != std::string::npos);
458    msg = std::string() + R"({"id":0,"method":"Profiler.enableSerializationTimeoutCheck","params":{"threshold": 5}})";
459    DispatchRequest request1(msg);
460    dispatcherImpl->Dispatch(request1);
461    if (channel) {
462        delete channel;
463        channel = nullptr;
464    }
465    ASSERT_TRUE(result == "{\"id\":0,\"result\":{}}");
466}
467
468HWTEST_F_L0(ProfilerImplTest, FrontendPreciseCoverageDeltaUpdate)
469{
470    std::string result = "";
471    std::function<void(const void*, const std::string &)> callback =
472        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
473    ProtocolChannel *channel = nullptr;
474    auto frontend = std::make_unique<ProfilerImpl::Frontend>(channel);
475    frontend->PreciseCoverageDeltaUpdate();
476    ASSERT_TRUE(result == "");
477    if (!channel) {
478        channel = new ProtocolHandler(callback, ecmaVm);
479    }
480    auto frontend1 = std::make_unique<ProfilerImpl::Frontend>(channel);
481    frontend1->PreciseCoverageDeltaUpdate();
482    if (channel) {
483        delete channel;
484        channel = nullptr;
485    }
486    ASSERT_TRUE(result.find("Profile.PreciseCoverageDeltaUpdate") != std::string::npos);
487}
488}  // namespace panda::test
489