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