1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 <fcntl.h>
17 #include <hwext/gtest-ext.h>
18 #include <hwext/gtest-tag.h>
19 #include <iostream>
20 #include <string>
21 #include <unistd.h>
22 
23 #include "file.h"
24 #include "trace_streamer_selector.h"
25 constexpr size_t G_FILE_PERMISSION = 664;
26 
27 using namespace testing::ext;
28 using namespace SysTuning;
29 using namespace SysTuning::TraceStreamer;
30 namespace SysTuning {
31 namespace TraceStreamer {
32 class ParserPbreaderTest : public testing::Test {
33 protected:
SetUpTestCase()34     static void SetUpTestCase() {}
TearDownTestCase()35     static void TearDownTestCase() {}
36 };
37 
38 /**
39  * @tc.name: HtracePbreaderParserTest
40  * @tc.desc: Test htrace parsing binary file export database
41  * @tc.type: FUNC
42  */
HWTEST_F(ParserPbreaderTest, HtracePbreaderParserTest, TestSize.Level1)43 HWTEST_F(ParserPbreaderTest, HtracePbreaderParserTest, TestSize.Level1)
44 {
45     TS_LOGI("test34-1");
46     const std::string tracePath = "../../test/resource/pbreader.htrace";
47     const std::string dbPath = "../../test/resource/test34-1_out.db";
48     constexpr size_t readSize = 1024;
49     constexpr uint32_t lineLength = 256;
50     if (access(tracePath.c_str(), F_OK) == 0) {
51         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
52             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
53         ta->EnableMetaTable(false);
54         int32_t fd(base::OpenFile(tracePath, O_RDONLY, G_FILE_PERMISSION));
55         while (true) {
56             std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(readSize);
57             auto rsize = base::Read(fd, buf.get(), readSize);
58 
59             if (rsize == 0) {
60                 break;
61             }
62             if (rsize < 0) {
63                 TS_LOGD("Reading trace file over (errno: %d, %s)", errno, strerror(errno));
64                 break;
65             }
66             if (!ta->ParseTraceDataSegment(std::move(buf), rsize, 0, 1)) {
67                 break;
68             };
69         }
70         ta->WaitForParserEnd();
71         close(fd);
72         ta->ExportDatabase(dbPath);
73         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
74         remove(dbPath.c_str());
75     } else {
76         EXPECT_TRUE(false);
77     }
78 }
79 
80 /**
81  * @tc.name: BytraceParserTest
82  * @tc.desc: Test bytrace parsing TXT file to export database
83  * @tc.type: FUNC
84  */
HWTEST_F(ParserPbreaderTest, BytraceParserTest, TestSize.Level1)85 HWTEST_F(ParserPbreaderTest, BytraceParserTest, TestSize.Level1)
86 {
87     TS_LOGI("test34-2");
88     const std::string tracePath = "../../test/resource/ut_bytrace_input_full.txt";
89     const std::string dbPath = "../../test/resource/test34-2_out.db";
90     constexpr size_t readSize = 1024 * 1024;
91     constexpr uint32_t lineLength = 256;
92 
93     if (access(tracePath.c_str(), F_OK) == 0) {
94         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
95             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
96         ta->EnableMetaTable(false);
97         int32_t fd(base::OpenFile(tracePath, O_RDONLY, G_FILE_PERMISSION));
98         while (true) {
99             std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(readSize);
100             auto rsize = base::Read(fd, buf.get(), readSize);
101             if (rsize == 0) {
102                 break;
103             }
104             if (rsize < 0) {
105                 TS_LOGD("Reading trace file failed (errno: %d, %s)", errno, strerror(errno));
106                 break;
107             }
108             if (!ta->ParseTraceDataSegment(std::move(buf), rsize, 0, 1)) {
109                 break;
110             };
111         }
112         ta->WaitForParserEnd();
113         close(fd);
114         ta->ExportDatabase(dbPath);
115         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
116         remove(dbPath.c_str());
117     } else {
118         EXPECT_TRUE(false);
119     }
120 }
121 
122 /**
123  * @tc.name: HtraceAndPerfParserTest
124  * @tc.desc: Test parsing htrace and perf binary file export database
125  * @tc.type: FUNC
126  */
HWTEST_F(ParserPbreaderTest, HtraceAndPerfParserTest, TestSize.Level1)127 HWTEST_F(ParserPbreaderTest, HtraceAndPerfParserTest, TestSize.Level1)
128 {
129     TS_LOGI("test34-3");
130     const std::string tracePath = "../../test/resource/htrace_perf.bin";
131     const std::string dbPath = "../../test/resource/test34-3_out.db";
132     constexpr size_t readSize = 1024;
133     constexpr uint32_t lineLength = 256;
134 
135     if (access(tracePath.c_str(), F_OK) == 0) {
136         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
137             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
138         ta->EnableMetaTable(false);
139         int32_t fd(base::OpenFile(tracePath, O_RDONLY, G_FILE_PERMISSION));
140         while (true) {
141             std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(readSize);
142             auto rsize = base::Read(fd, buf.get(), readSize);
143 
144             if (rsize == 0) {
145                 break;
146             }
147             if (rsize < 0) {
148                 TS_LOGD("Reading trace file over (errno: %d, %s)", errno, strerror(errno));
149                 break;
150             }
151             if (!ta->ParseTraceDataSegment(std::move(buf), rsize, 0, 1)) {
152                 break;
153             };
154         }
155         ta->WaitForParserEnd();
156         close(fd);
157         ta->ExportDatabase(dbPath);
158         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
159         remove(dbPath.c_str());
160     } else {
161         EXPECT_TRUE(false);
162     }
163 }
164 
165 /**
166  * @tc.name: HtraceAndEbpfParserTest
167  * @tc.desc: Test parsing htrace and ebpf binary file export database
168  * @tc.type: FUNC
169  */
HWTEST_F(ParserPbreaderTest, HtraceAndEbpfParserTest, TestSize.Level1)170 HWTEST_F(ParserPbreaderTest, HtraceAndEbpfParserTest, TestSize.Level1)
171 {
172     TS_LOGI("test34-4");
173     const std::string tracePath = "../../test/resource/htrace_ebpf.bin";
174     const std::string dbPath = "../../test/resource/test34-4_out.db";
175     constexpr size_t readSize = 1024;
176     constexpr uint32_t lineLength = 256;
177 
178     if (access(tracePath.c_str(), F_OK) == 0) {
179         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
180             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
181         ta->EnableMetaTable(false);
182         int32_t fd(base::OpenFile(tracePath, O_RDONLY, G_FILE_PERMISSION));
183         while (true) {
184             std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(readSize);
185             auto rsize = base::Read(fd, buf.get(), readSize);
186 
187             if (rsize == 0) {
188                 break;
189             }
190             if (rsize < 0) {
191                 TS_LOGD("Reading trace file over (errno: %d, %s)", errno, strerror(errno));
192                 break;
193             }
194             if (!ta->ParseTraceDataSegment(std::move(buf), rsize, 0, 1)) {
195                 break;
196             };
197         }
198         ta->WaitForParserEnd();
199         close(fd);
200         ta->ExportDatabase(dbPath);
201         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
202         remove(dbPath.c_str());
203     } else {
204         EXPECT_TRUE(false);
205     }
206 }
207 
208 /**
209  * @tc.name: NoHeaderPerfParseTest
210  * @tc.desc: Test parsing perf(no profiler header) binary file export database
211  * @tc.type: FUNC
212  */
HWTEST_F(ParserPbreaderTest, NoHeaderPerfParseTest, TestSize.Level1)213 HWTEST_F(ParserPbreaderTest, NoHeaderPerfParseTest, TestSize.Level1)
214 {
215     TS_LOGI("test34-5");
216     const std::string noHeaderPerfPath = "../../test/resource/htrace_perf_no_profiler_header.bin";
217     const std::string dbPath = "../../test/resource/test34-5_out.db";
218     constexpr size_t readSize = 1024;
219     constexpr uint32_t lineLength = 256;
220 
221     if (access(noHeaderPerfPath.c_str(), F_OK) == 0) {
222         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
223             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
224         ta->EnableMetaTable(false);
225         int32_t fd(base::OpenFile(noHeaderPerfPath, O_RDONLY, G_FILE_PERMISSION));
226         while (true) {
227             std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(readSize);
228             auto rsize = base::Read(fd, buff.get(), readSize);
229             if (rsize == 0) {
230                 break;
231             }
232             if (rsize < 0) {
233                 TS_LOGD("Reading trace file over (errno: %d, %s)", errno, strerror(errno));
234                 break;
235             }
236             if (!ta->ParseTraceDataSegment(std::move(buff), rsize, 0, 1)) {
237                 break;
238             };
239         }
240         ta->WaitForParserEnd();
241         close(fd);
242         ta->ExportDatabase(dbPath);
243         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
244         remove(dbPath.c_str());
245     } else {
246         EXPECT_TRUE(false);
247     }
248 }
249 /**
250  * @tc.name: PerfCompressedParseTest
251  * @tc.desc: Test parsing perf(compressed callstack) binary file export database
252  * @tc.type: FUNC
253  */
HWTEST_F(ParserPbreaderTest, PerfCompressedParseTest, TestSize.Level1)254 HWTEST_F(ParserPbreaderTest, PerfCompressedParseTest, TestSize.Level1)
255 {
256     TS_LOGI("test34-6");
257     const std::string compressedPerfPath = "../../test/resource/perfCompressed.data";
258     const std::string dbPath = "../../test/resource/test34-6_out.db";
259     constexpr size_t readSize = 1024;
260     constexpr uint32_t lineLength = 256;
261 
262     if (access(compressedPerfPath.c_str(), F_OK) == 0) {
263         std::unique_ptr<SysTuning::TraceStreamer::TraceStreamerSelector> ta =
264             std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
265         ta->EnableMetaTable(false);
266         int32_t fd(base::OpenFile(compressedPerfPath, O_RDONLY, G_FILE_PERMISSION));
267         while (true) {
268             std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(readSize);
269             auto rsize = base::Read(fd, buffer.get(), readSize);
270             if (rsize == 0) {
271                 break;
272             }
273             if (rsize < 0) {
274                 TS_LOGD("Reading compressed stack perf trace file over (errno: %d, %s)", errno, strerror(errno));
275                 break;
276             }
277             if (!ta->ParseTraceDataSegment(std::move(buffer), rsize, 0, 1)) {
278                 break;
279             };
280         }
281         ta->WaitForParserEnd();
282         close(fd);
283         ta->ExportDatabase(dbPath);
284         EXPECT_TRUE(access(dbPath.c_str(), F_OK) == 0);
285         remove(dbPath.c_str());
286     } else {
287         EXPECT_TRUE(false);
288     }
289 }
290 } // namespace TraceStreamer
291 } // namespace SysTuning
292