1e509ee18Sopenharmony_ci/*
2e509ee18Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License.
5e509ee18Sopenharmony_ci * You may obtain a copy of the License at
6e509ee18Sopenharmony_ci *
7e509ee18Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e509ee18Sopenharmony_ci *
9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and
13e509ee18Sopenharmony_ci * limitations under the License.
14e509ee18Sopenharmony_ci */
15e509ee18Sopenharmony_ci
16e509ee18Sopenharmony_ci#include "agent/tracing_impl.h"
17e509ee18Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
18e509ee18Sopenharmony_ci#include "protocol_handler.h"
19e509ee18Sopenharmony_ci
20e509ee18Sopenharmony_ciusing namespace panda::ecmascript;
21e509ee18Sopenharmony_ciusing namespace panda::ecmascript::tooling;
22e509ee18Sopenharmony_ci
23e509ee18Sopenharmony_cinamespace panda::test {
24e509ee18Sopenharmony_ciclass TracingImplTest : public testing::Test {
25e509ee18Sopenharmony_cipublic:
26e509ee18Sopenharmony_ci    static void SetUpTestCase()
27e509ee18Sopenharmony_ci    {
28e509ee18Sopenharmony_ci        GTEST_LOG_(INFO) << "SetUpTestCase";
29e509ee18Sopenharmony_ci    }
30e509ee18Sopenharmony_ci
31e509ee18Sopenharmony_ci    static void TearDownTestCase()
32e509ee18Sopenharmony_ci    {
33e509ee18Sopenharmony_ci        GTEST_LOG_(INFO) << "TearDownCase";
34e509ee18Sopenharmony_ci    }
35e509ee18Sopenharmony_ci
36e509ee18Sopenharmony_ci    void SetUp() override
37e509ee18Sopenharmony_ci    {
38e509ee18Sopenharmony_ci        TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
39e509ee18Sopenharmony_ci    }
40e509ee18Sopenharmony_ci
41e509ee18Sopenharmony_ci    void TearDown() override
42e509ee18Sopenharmony_ci    {
43e509ee18Sopenharmony_ci        TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
44e509ee18Sopenharmony_ci    }
45e509ee18Sopenharmony_ci
46e509ee18Sopenharmony_ciprotected:
47e509ee18Sopenharmony_ci    EcmaVM *ecmaVm {nullptr};
48e509ee18Sopenharmony_ci    EcmaHandleScope *scope {nullptr};
49e509ee18Sopenharmony_ci    JSThread *thread {nullptr};
50e509ee18Sopenharmony_ci};
51e509ee18Sopenharmony_ci
52e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, StartAndEndTest)
53e509ee18Sopenharmony_ci{
54e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
55e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
56e509ee18Sopenharmony_ci    auto params = std::make_unique<StartParams>();
57e509ee18Sopenharmony_ci    params->SetCategories("cpu_profiler");
58e509ee18Sopenharmony_ci    DispatchResponse response = tracing->Start(std::move(params));
59e509ee18Sopenharmony_ci    ASSERT_TRUE(response.IsOk());
60e509ee18Sopenharmony_ci
61e509ee18Sopenharmony_ci    auto profileInfo = tracing->End();
62e509ee18Sopenharmony_ci    ASSERT_TRUE(profileInfo != nullptr);
63e509ee18Sopenharmony_ci}
64e509ee18Sopenharmony_ci
65e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, GetCategoriesTest)
66e509ee18Sopenharmony_ci{
67e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
68e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
69e509ee18Sopenharmony_ci    std::vector<std::string> categories = {};
70e509ee18Sopenharmony_ci    DispatchResponse response = tracing->GetCategories(categories);
71e509ee18Sopenharmony_ci    ASSERT_TRUE(response.GetMessage() == "GetCategories not support now.");
72e509ee18Sopenharmony_ci}
73e509ee18Sopenharmony_ci
74e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, RecordClockSyncMarkerTest)
75e509ee18Sopenharmony_ci{
76e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
77e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
78e509ee18Sopenharmony_ci    std::string syncId;
79e509ee18Sopenharmony_ci    DispatchResponse response = tracing->RecordClockSyncMarker(syncId);
80e509ee18Sopenharmony_ci    ASSERT_TRUE(response.GetMessage() == "RecordClockSyncMarker not support now.");
81e509ee18Sopenharmony_ci}
82e509ee18Sopenharmony_ci
83e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, RequestMemoryDumpTest)
84e509ee18Sopenharmony_ci{
85e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
86e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
87e509ee18Sopenharmony_ci    auto params = std::make_unique<RequestMemoryDumpParams>();
88e509ee18Sopenharmony_ci    std::string dumpGuid;
89e509ee18Sopenharmony_ci    bool success = false;
90e509ee18Sopenharmony_ci    DispatchResponse response = tracing->RequestMemoryDump(std::move(params), dumpGuid, success);
91e509ee18Sopenharmony_ci    ASSERT_TRUE(response.GetMessage() == "RequestMemoryDump not support now.");
92e509ee18Sopenharmony_ci}
93e509ee18Sopenharmony_ci
94e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplDispatchTest)
95e509ee18Sopenharmony_ci{
96e509ee18Sopenharmony_ci    std::string result = "";
97e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
98e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
99e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
100e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
101e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
102e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.Test","params":{}})";
103e509ee18Sopenharmony_ci    DispatchRequest request(msg);
104e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
105e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("Unknown method: Test") != std::string::npos);
106e509ee18Sopenharmony_ci    msg = std::string() + R"({"id":0,"method":"Debugger.end","params":{}})";
107e509ee18Sopenharmony_ci    DispatchRequest request1 = DispatchRequest(msg);
108e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request1);
109e509ee18Sopenharmony_ci    if (channel) {
110e509ee18Sopenharmony_ci        delete channel;
111e509ee18Sopenharmony_ci        channel = nullptr;
112e509ee18Sopenharmony_ci    }
113e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("\"id\":0,") != std::string::npos);
114e509ee18Sopenharmony_ci}
115e509ee18Sopenharmony_ci
116e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplEndTest)
117e509ee18Sopenharmony_ci{
118e509ee18Sopenharmony_ci    std::string result = "";
119e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
120e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
121e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
122e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
123e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
124e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.end","params":{}})";
125e509ee18Sopenharmony_ci        DispatchRequest request = DispatchRequest(msg);
126e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
127e509ee18Sopenharmony_ci    if (channel) {
128e509ee18Sopenharmony_ci        delete channel;
129e509ee18Sopenharmony_ci        channel = nullptr;
130e509ee18Sopenharmony_ci    }
131e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("\"id\":0,") != std::string::npos);
132e509ee18Sopenharmony_ci}
133e509ee18Sopenharmony_ci
134e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplGetCategoriesTest)
135e509ee18Sopenharmony_ci{
136e509ee18Sopenharmony_ci    std::string result = "";
137e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
138e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
139e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
140e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
141e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
142e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.getCategories","params":{}})";
143e509ee18Sopenharmony_ci        DispatchRequest request = DispatchRequest(msg);
144e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
145e509ee18Sopenharmony_ci    if (channel) {
146e509ee18Sopenharmony_ci        delete channel;
147e509ee18Sopenharmony_ci        channel = nullptr;
148e509ee18Sopenharmony_ci    }
149e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("GetCategories not support now") != std::string::npos);
150e509ee18Sopenharmony_ci}
151e509ee18Sopenharmony_ci
152e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplRecordClockSyncMarkerTest)
153e509ee18Sopenharmony_ci{
154e509ee18Sopenharmony_ci    std::string result = "";
155e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
156e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
157e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
158e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
159e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
160e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.recordClockSyncMarker","params":{}})";
161e509ee18Sopenharmony_ci        DispatchRequest request = DispatchRequest(msg);
162e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
163e509ee18Sopenharmony_ci    if (channel) {
164e509ee18Sopenharmony_ci        delete channel;
165e509ee18Sopenharmony_ci        channel = nullptr;
166e509ee18Sopenharmony_ci    }
167e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("RecordClockSyncMarker not support now.") != std::string::npos);
168e509ee18Sopenharmony_ci}
169e509ee18Sopenharmony_ci
170e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplRequestMemoryDumpTest)
171e509ee18Sopenharmony_ci{
172e509ee18Sopenharmony_ci    std::string result = "";
173e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
174e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
175e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
176e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
177e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
178e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.requestMemoryDump","params":{}})";
179e509ee18Sopenharmony_ci        DispatchRequest request = DispatchRequest(msg);
180e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
181e509ee18Sopenharmony_ci    if (channel) {
182e509ee18Sopenharmony_ci        delete channel;
183e509ee18Sopenharmony_ci        channel = nullptr;
184e509ee18Sopenharmony_ci    }
185e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("RequestMemoryDump not support now.") != std::string::npos);
186e509ee18Sopenharmony_ci}
187e509ee18Sopenharmony_ci
188e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, DispatcherImplStartDumpTest)
189e509ee18Sopenharmony_ci{
190e509ee18Sopenharmony_ci    std::string result = "";
191e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
192e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
193e509ee18Sopenharmony_ci    ProtocolChannel *channel =  new ProtocolHandler(callback, ecmaVm);
194e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(ecmaVm, channel);
195e509ee18Sopenharmony_ci    auto dispatcherImpl = std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
196e509ee18Sopenharmony_ci    std::string msg = std::string() + R"({"id":0,"method":"Debugger.start","params":{"categories":"cpu_profiler"}})";
197e509ee18Sopenharmony_ci    DispatchRequest request = DispatchRequest(msg);
198e509ee18Sopenharmony_ci    dispatcherImpl->Dispatch(request);
199e509ee18Sopenharmony_ci    if (channel) {
200e509ee18Sopenharmony_ci        delete channel;
201e509ee18Sopenharmony_ci        channel = nullptr;
202e509ee18Sopenharmony_ci    }
203e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("\"id\":0,") != std::string::npos);
204e509ee18Sopenharmony_ci}
205e509ee18Sopenharmony_ci
206e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, FrontendBufferUsageTest)
207e509ee18Sopenharmony_ci{
208e509ee18Sopenharmony_ci    std::string result = "";
209e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
210e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
211e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
212e509ee18Sopenharmony_ci    auto frontend = std::make_unique<TracingImpl::Frontend>(channel);
213e509ee18Sopenharmony_ci    frontend->BufferUsage(0, 0, 0);
214e509ee18Sopenharmony_ci    ASSERT_TRUE(result == "");
215e509ee18Sopenharmony_ci    if (!channel) {
216e509ee18Sopenharmony_ci        channel =  new ProtocolHandler(callback, ecmaVm);
217e509ee18Sopenharmony_ci    }
218e509ee18Sopenharmony_ci    auto frontend1 = std::make_unique<TracingImpl::Frontend>(channel);
219e509ee18Sopenharmony_ci    frontend1->BufferUsage(0, 0, 0);
220e509ee18Sopenharmony_ci    if (channel) {
221e509ee18Sopenharmony_ci        delete channel;
222e509ee18Sopenharmony_ci        channel = nullptr;
223e509ee18Sopenharmony_ci    }
224e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("Tracing.bufferUsage") != std::string::npos);
225e509ee18Sopenharmony_ci}
226e509ee18Sopenharmony_ci
227e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, FrontendDataCollectedTest)
228e509ee18Sopenharmony_ci{
229e509ee18Sopenharmony_ci    int64_t ts = 604898475815;
230e509ee18Sopenharmony_ci    TraceEvent event("timeline", "UpdateCounters", "I", getpid(), 1415);
231e509ee18Sopenharmony_ci    event.SetTs(ts);
232e509ee18Sopenharmony_ci    event.SetTts(ts);
233e509ee18Sopenharmony_ci    event.SetS("t");
234e509ee18Sopenharmony_ci    std::string args = "{\"data\":{\"jsHeapSizeUsed\":" + std::to_string(1024) + "}}";
235e509ee18Sopenharmony_ci    event.SetArgs(args);
236e509ee18Sopenharmony_ci    std::unique_ptr<std::vector<TraceEvent>> traceEvents = std::make_unique<std::vector<TraceEvent>>();
237e509ee18Sopenharmony_ci    traceEvents->emplace_back(event);
238e509ee18Sopenharmony_ci
239e509ee18Sopenharmony_ci    std::string result = "";
240e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
241e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
242e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
243e509ee18Sopenharmony_ci    auto frontend = std::make_unique<TracingImpl::Frontend>(channel);
244e509ee18Sopenharmony_ci    frontend->DataCollected(std::move(traceEvents));
245e509ee18Sopenharmony_ci    ASSERT_TRUE(result == "");
246e509ee18Sopenharmony_ci    if (!channel) {
247e509ee18Sopenharmony_ci        channel =  new ProtocolHandler(callback, ecmaVm);
248e509ee18Sopenharmony_ci    }
249e509ee18Sopenharmony_ci    auto frontend1 = std::make_unique<TracingImpl::Frontend>(channel);
250e509ee18Sopenharmony_ci    std::unique_ptr<std::vector<TraceEvent>> traceEvents1 = std::make_unique<std::vector<TraceEvent>>();
251e509ee18Sopenharmony_ci    traceEvents1->emplace_back(event);
252e509ee18Sopenharmony_ci    frontend1->DataCollected(std::move(traceEvents1));
253e509ee18Sopenharmony_ci    if (channel) {
254e509ee18Sopenharmony_ci        delete channel;
255e509ee18Sopenharmony_ci        channel = nullptr;
256e509ee18Sopenharmony_ci    }
257e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("Tracing.dataCollected") != std::string::npos);
258e509ee18Sopenharmony_ci}
259e509ee18Sopenharmony_ci
260e509ee18Sopenharmony_ciHWTEST_F_L0(TracingImplTest, FrontendTracingCompleteTest)
261e509ee18Sopenharmony_ci{
262e509ee18Sopenharmony_ci    std::string result = "";
263e509ee18Sopenharmony_ci    std::function<void(const void*, const std::string &)> callback =
264e509ee18Sopenharmony_ci        [&result]([[maybe_unused]] const void *ptr, const std::string &temp) { result = temp; };
265e509ee18Sopenharmony_ci    ProtocolChannel *channel = nullptr;
266e509ee18Sopenharmony_ci    auto frontend = std::make_unique<TracingImpl::Frontend>(channel);
267e509ee18Sopenharmony_ci    frontend->TracingComplete();
268e509ee18Sopenharmony_ci    ASSERT_TRUE(result == "");
269e509ee18Sopenharmony_ci    if (!channel) {
270e509ee18Sopenharmony_ci        channel =  new ProtocolHandler(callback, ecmaVm);
271e509ee18Sopenharmony_ci    }
272e509ee18Sopenharmony_ci    auto frontend1 = std::make_unique<TracingImpl::Frontend>(channel);
273e509ee18Sopenharmony_ci    frontend1->TracingComplete();
274e509ee18Sopenharmony_ci    if (channel) {
275e509ee18Sopenharmony_ci        delete channel;
276e509ee18Sopenharmony_ci        channel = nullptr;
277e509ee18Sopenharmony_ci    }
278e509ee18Sopenharmony_ci    ASSERT_TRUE(result.find("Tracing.tracingComplete") != std::string::npos);
279e509ee18Sopenharmony_ci}
280e509ee18Sopenharmony_ci}  // namespace panda::test