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