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 <fstream> 17 #include <fcntl.h> 18 #include <hwext/gtest-ext.h> 19 #include <hwext/gtest-tag.h> 20 #include <memory> 21 #include <string> 22 23 #include "export_test.h" 24 #include "file.h" 25 #include "rawtrace_parser.h" 26 #include "parser/common_types.h" 27 #include "string_help.h" 28 #include "trace_streamer_selector.h" 29 30 using namespace testing::ext; 31 using namespace SysTuning::TraceStreamer; 32 using namespace SysTuning::base; 33 34 namespace SysTuning { 35 namespace TraceStreamer { 36 bool ParseTraceFile(TraceStreamerSelector &ts, const std::string &tracePath); 37 38 constexpr uint64_t PRINTK_VALID_ADDR = 0xffffffc011bdd3ea; 39 class RawTraceParserTest : public ::testing::Test { 40 public: SetUp()41 void SetUp() 42 { 43 selector_.InitFilter(); 44 selector_.EnableMetaTable(false); 45 if (access(rawTraceDataPath_.c_str(), F_OK) == 0) { 46 dataFs_.open(rawTraceDataPath_, std::ios::binary | std::ios::in); 47 } 48 parser_ = std::make_unique<RawTraceParser>(selector_.traceDataCache_.get(), selector_.streamFilters_.get()); 49 } 50 TearDown()51 void TearDown() 52 { 53 dataFs_.close(); 54 } 55 ChunkToString(std::ifstream & fs)56 std::string ChunkToString(std::ifstream &fs) 57 { 58 std::string line; 59 std::stringstream ss; 60 while (std::getline(fs, line)) { 61 if (StartWith(line, chunkEndCmd_)) { 62 break; 63 } 64 ss << line << '\n'; 65 } 66 return ss.str(); 67 } 68 69 public: 70 SysTuning::TraceStreamer::TraceStreamerSelector selector_ = {}; 71 std::unique_ptr<RawTraceParser> parser_; 72 const std::string fileHeaderCmd_ = "file_header:"; 73 const std::string headPageFormatsCmd_ = "headPageFormats:"; 74 const std::string printkFormatsCmd_ = "printkFormats:"; 75 const std::string kAllSymsCmd_ = "kAllSyms:"; 76 const std::string cmdlinesCmd_ = "cmdlines:"; 77 const std::string tgidsCmd_ = "tgids:"; 78 const std::string cpuDataCmd_ = "cpuData:"; 79 const std::string chunkEndCmd_ = "-end-"; 80 const std::string rawTraceBinPath_ = "../../test/resource/rawtrace.bin"; 81 const std::string rawTraceDataPath_ = "../../test/resource/rawtrace.data"; 82 std::string line_; 83 std::string chunckStr_; 84 const size_t bufferSize_ = 1024 * 1024; 85 std::ifstream dataFs_; 86 }; 87 88 /** 89 * @tc.name: ParseAllData 90 * @tc.desc: Test ParseTraceDataSegment interface Parse all data 91 * @tc.type: FUNC 92 */ 93 HWTEST_F(RawTraceParserTest, ParseAllData, TestSize.Level1) 94 { 95 TS_LOGI("test38-1"); 96 EXPECT_TRUE(ParseTraceFile(selector_, rawTraceBinPath_)); 97 } 98 /** 99 * @tc.name: ParseFileHeader 100 * @tc.desc: Test ParseTraceDataSegment interface Parse file header 101 * @tc.type: FUNC 102 */ 103 HWTEST_F(RawTraceParserTest, ParseFileHeader, TestSize.Level1) 104 { 105 TS_LOGI("test38-2"); 106 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 107 while (std::getline(dataFs_, line_)) { 108 if (StartWith(line_, fileHeaderCmd_)) { 109 chunckStr_ = ChunkToString(dataFs_); 110 auto &packagesBuffer = parser_->packagesBuffer_; 111 auto packagesCurIter = packagesBuffer.begin(); 112 EXPECT_FALSE(parser_->InitRawTraceFileHeader(packagesCurIter)); 113 const uint8_t *data = reinterpret_cast<const uint8_t *>(chunckStr_.c_str()); 114 packagesBuffer.insert(packagesBuffer.end(), data, data + chunckStr_.size()); 115 EXPECT_TRUE(parser_->InitRawTraceFileHeader(packagesCurIter)); 116 break; 117 } 118 } 119 } 120 /** 121 * @tc.name: HandleHeadPage 122 * @tc.desc: Test ParseTraceDataSegment interface Handle head page format 123 * @tc.type: FUNC 124 */ 125 HWTEST_F(RawTraceParserTest, HandleHeadPage, TestSize.Level1) 126 { 127 TS_LOGI("test38-3"); 128 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 129 // empty parse 130 EXPECT_FALSE(parser_->ftraceProcessor_->HandleHeaderPageFormat(chunckStr_)); 131 while (std::getline(dataFs_, line_)) { 132 if (StartWith(line_, headPageFormatsCmd_)) { 133 chunckStr_ = ChunkToString(dataFs_); 134 EXPECT_TRUE(parser_->ftraceProcessor_->HandleHeaderPageFormat(chunckStr_)); 135 break; 136 } 137 } 138 std::string noCommitField = R"(field: u64 timestamp; offset:0; size:8; signed:0; 139 field: int overwrite; offset:8; size:1; signed:1; 140 field: char data; offset:16; size:4080; signed:0;)"; 141 EXPECT_FALSE(parser_->ftraceProcessor_->HandleHeaderPageFormat(noCommitField)); 142 } 143 /** 144 * @tc.name: HandlePrintkFormats 145 * @tc.desc: Test ParseTraceDataSegment interface Handle printk formats 146 * @tc.type: FUNC 147 */ 148 HWTEST_F(RawTraceParserTest, HandlePrintkFormats, TestSize.Level1) 149 { 150 TS_LOGI("test38-4"); 151 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 152 while (std::getline(dataFs_, line_)) { 153 if (StartWith(line_, printkFormatsCmd_)) { 154 chunckStr_ = ChunkToString(dataFs_); 155 EXPECT_TRUE(PrintkFormatsProcessor::GetInstance().HandlePrintkSyms(chunckStr_)); 156 break; 157 } 158 } 159 std::string sym = PrintkFormatsProcessor::GetInstance().GetSymbol(PRINTK_VALID_ADDR); 160 EXPECT_TRUE(sym != "NULL"); 161 PrintkFormatsProcessor::GetInstance().Clear(); 162 std::string errPrintkFormats = R"(ffffffc010001578 T __entry_text_start 163 1409 HitraceDumpTest 164 250 239 165 )"; 166 EXPECT_FALSE(PrintkFormatsProcessor::GetInstance().HandlePrintkSyms(errPrintkFormats)); 167 } 168 /** 169 * @tc.name: HandleKallSyms 170 * @tc.desc: Test ParseTraceDataSegment interface Handle kAllSyms formats 171 * @tc.type: FUNC 172 */ 173 HWTEST_F(RawTraceParserTest, HandleKallSyms, TestSize.Level1) 174 { 175 TS_LOGI("test38-5"); 176 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 177 // empty parse 178 EXPECT_FALSE(parser_->ksymsProcessor_->HandleKallSyms(chunckStr_)); 179 while (std::getline(dataFs_, line_)) { 180 if (StartWith(line_, kAllSymsCmd_)) { 181 chunckStr_ = ChunkToString(dataFs_); 182 EXPECT_TRUE(parser_->ksymsProcessor_->HandleKallSyms(chunckStr_)); 183 break; 184 } 185 } 186 } 187 /** 188 * @tc.name: HandleCmdlines 189 * @tc.desc: Test ParseTraceDataSegment interface Handle cmdlines 190 * @tc.type: FUNC 191 */ 192 HWTEST_F(RawTraceParserTest, HandleCmdlines, TestSize.Level1) 193 { 194 TS_LOGI("test38-6"); 195 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 196 // empty parse 197 EXPECT_FALSE(parser_->ftraceProcessor_->HandleCmdlines(chunckStr_)); 198 while (std::getline(dataFs_, line_)) { 199 if (StartWith(line_, cmdlinesCmd_)) { 200 chunckStr_ = ChunkToString(dataFs_); 201 EXPECT_TRUE(parser_->ftraceProcessor_->HandleCmdlines(chunckStr_)); 202 break; 203 } 204 } 205 std::string errCmdlineFormats = "162,kworker/u8:2\n1409:HitraceDumpTest\n250-239"; 206 EXPECT_FALSE(parser_->ftraceProcessor_->HandleCmdlines(errCmdlineFormats)); 207 } 208 /** 209 * @tc.name: HandleTgids 210 * @tc.desc: Test ParseTraceDataSegment interface Handle tgids 211 * @tc.type: FUNC 212 */ 213 HWTEST_F(RawTraceParserTest, HandleTgids, TestSize.Level1) 214 { 215 TS_LOGI("test38-7"); 216 EXPECT_TRUE(dataFs_.is_open() && parser_ != nullptr); 217 // empty parse 218 EXPECT_FALSE(parser_->ftraceProcessor_->HandleTgids(chunckStr_)); 219 while (std::getline(dataFs_, line_)) { 220 if (StartWith(line_, tgidsCmd_)) { 221 chunckStr_ = ChunkToString(dataFs_); 222 EXPECT_TRUE(parser_->ftraceProcessor_->HandleTgids(chunckStr_)); 223 break; 224 } 225 } 226 } 227 } // namespace TraceStreamer 228 } // namespace SysTuning 229