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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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