• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ptreader_parser.h"
24 #include "file.h"
25 #include "pbreader_parser.h"
26 #include "trace_streamer_selector.h"
27 
28 using namespace testing::ext;
29 using namespace SysTuning;
30 using namespace SysTuning::TraceStreamer;
31 namespace SysTuning {
32 namespace TraceStreamer {
33 constexpr size_t G_FILE_PERMISSION = 664;
34 const uint32_t PROFILE_HEADER = 1024;
35 constexpr size_t READ_SIZE = 1024;
36 
37 class SplitFileDataTest : public testing::Test {
38 protected:
SetUpTestCase()39     static void SetUpTestCase() {}
TearDownTestCase()40     static void TearDownTestCase() {}
41 
ParseData(std::unique_ptr<TraceStreamerSelector> & ta,const std::string path)42     void ParseData(std::unique_ptr<TraceStreamerSelector> &ta, const std::string path)
43     {
44         ta->EnableMetaTable(false);
45 
46         size_t readSize = 0;
47         int32_t fd(base::OpenFile(path, O_RDONLY, G_FILE_PERMISSION));
48         while (true) {
49             std::unique_ptr<uint8_t[]> buf = std::make_unique<uint8_t[]>(READ_SIZE);
50             auto rsize = base::Read(fd, buf.get(), READ_SIZE);
51             if (rsize == 0) {
52                 break;
53             }
54             if (rsize < 0) {
55                 TS_LOGD("Reading trace file over (errno: %d, %s)", errno, strerror(errno));
56                 break;
57             }
58             if (!ta->ParseTraceDataSegment(std::move(buf), rsize, 1, 1)) {
59                 break;
60             };
61 
62             dataBuf_ = std::make_unique<uint8_t[]>(readSize + rsize);
63             memcpy_s(dataBuf_.get() + readSize, rsize, buf.get(), rsize);
64             readSize += rsize;
65         }
66 
67         ta->WaitForParserEnd();
68         close(fd);
69     }
70 
CheckData(std::unique_ptr<TraceStreamerSelector> & ta,const std::string path)71     bool CheckData(std::unique_ptr<TraceStreamerSelector> &ta, const std::string path)
72     {
73         std::ifstream inputFile(path, std::ios::binary);
74         if (!inputFile.is_open()) {
75             std::cerr << "Failed to open file: " << path << std::endl;
76             return false;
77         }
78 
79         auto splitResult = ta->GetPbreaderParser()->GetEbpfDataParser()->GetEbpfSplitResult();
80         uint64_t headDataSize = 0;
81         for (const auto &itemHtrace : ta->GetPbreaderParser()->GetPbreaderSplitData()) {
82             headDataSize += itemHtrace.second;
83         }
84         auto profilerHeader = ta->GetPbreaderParser()->GetProfilerHeader();
85         profilerHeader.data.length = PROFILE_HEADER + headDataSize;
86         std::string bufferData(reinterpret_cast<char *>(&profilerHeader), sizeof(profilerHeader));
87         uint64_t dataSize = 0;
88         for (auto it = splitResult.begin(); it != splitResult.end(); ++it) {
89             if (it->type == (int32_t)SplitDataDataType::SPLIT_FILE_JSON) {
90                 dataSize += it->originSeg.size;
91             }
92         }
93         auto combinedBuf = std::make_unique<uint8_t[]>(dataSize + PROFILE_HEADER + headDataSize);
94         std::copy(bufferData.begin(), bufferData.end(), combinedBuf.get());
95         std::streamsize currentOffset = PROFILE_HEADER;
96         for (const auto &itemHtrace : ta->GetPbreaderParser()->GetPbreaderSplitData()) {
97             inputFile.seekg(itemHtrace.first);
98             inputFile.read(reinterpret_cast<char *>(combinedBuf.get()) + currentOffset, itemHtrace.second);
99             currentOffset += itemHtrace.second;
100         }
101         for (auto it = splitResult.begin(); it != splitResult.end(); ++it) {
102             if (it->type == (int32_t)SplitDataDataType::SPLIT_FILE_JSON) {
103                 inputFile.seekg(it->originSeg.offset);
104                 inputFile.read(reinterpret_cast<char *>(combinedBuf.get()) + currentOffset, it->originSeg.size);
105                 currentOffset += it->originSeg.size;
106             }
107             if (!inputFile) {
108                 std::cerr << "Error reading from file." << std::endl;
109                 return false;
110             }
111         }
112         std::unique_ptr<TraceStreamerSelector> ts = std::make_unique<TraceStreamerSelector>();
113         bool ret = ts->ParseTraceDataSegment(std::move(combinedBuf), dataSize + PROFILE_HEADER + headDataSize, 1, 1);
114         return ret;
115     }
116 
117 public:
118     std::unique_ptr<uint8_t[]> dataBuf_;
119 };
120 
121 /**
122  * @tc.name: SplitFileDataByHtraceTest
123  * @tc.desc: Test htrace parsing binary file export database
124  * @tc.type: FUNC
125  */
126 HWTEST_F(SplitFileDataTest, SplitFileDataByHtraceTest, TestSize.Level1)
127 {
128     TS_LOGI("test43-1");
129     const std::string tracePath = "../../test/resource/hiprofiler_data_ability.htrace";
130     if (access(tracePath.c_str(), F_OK) == 0) {
131         auto ta = std::make_unique<TraceStreamerSelector>();
132         ta->minTs_ = 1502026311556913964;
133         ta->maxTs_ = 1502026330073755298;
134         ParseData(ta, tracePath);
135 
136         std::ifstream inputFile(tracePath, std::ios::binary);
137         if (!inputFile.is_open()) {
138             std::cerr << "Failed to open file: " << tracePath << std::endl;
139             EXPECT_TRUE(false);
140         }
141         uint64_t dataSize = 0;
142         auto profilerHeader = ta->GetPbreaderParser()->GetProfilerHeader();
143 
144         for (const auto &itemHtrace : ta->GetPbreaderParser()->GetPbreaderSplitData()) {
145             dataSize += itemHtrace.second;
146         }
147         profilerHeader.data.length = PROFILE_HEADER + dataSize;
148         std::string buffer(reinterpret_cast<char *>(&profilerHeader), sizeof(profilerHeader));
149         std::unique_ptr<uint8_t[]> combinedBuf = std::make_unique<uint8_t[]>(dataSize + PROFILE_HEADER);
150         std::copy(buffer.begin(), buffer.end(), combinedBuf.get());
151         std::streamsize currentOffset = PROFILE_HEADER;
152         for (const auto &itemHtrace : ta->GetPbreaderParser()->GetPbreaderSplitData()) {
153             inputFile.seekg(itemHtrace.first);
154             inputFile.read(reinterpret_cast<char *>(combinedBuf.get()) + currentOffset, itemHtrace.second);
155             currentOffset += itemHtrace.second;
156             if (!inputFile) {
157                 std::cerr << "Error reading from file." << std::endl;
158                 EXPECT_TRUE(false);
159             }
160         }
161         std::unique_ptr<TraceStreamerSelector> ts = std::make_unique<TraceStreamerSelector>();
162         EXPECT_TRUE(ts->ParseTraceDataSegment(std::move(combinedBuf), dataSize + PROFILE_HEADER, 1, 1));
163     } else {
164         EXPECT_TRUE(false);
165     }
166 }
167 
168 /**
169  * @tc.name: SplitFileDataByHtraceTest
170  * @tc.desc: Test htrace parsing binary file export database
171  * @tc.type: FUNC
172  */
173 HWTEST_F(SplitFileDataTest, SplitFileDataBySystraceTest, TestSize.Level1)
174 {
175     TS_LOGI("test43-2");
176     const std::string tracePath = "../../test/resource/trace_small_10.systrace";
177     if (access(tracePath.c_str(), F_OK) == 0) {
178         auto ta = std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
179         ta->minTs_ = 88029692887000;
180         ta->maxTs_ = 88032820831000;
181         ParseData(ta, tracePath);
182 
183         std::unique_ptr<TraceStreamerSelector> ts = std::make_unique<TraceStreamerSelector>();
184         EXPECT_TRUE(ts->ParseTraceDataSegment(std::move(dataBuf_),
185                                               ta->GetPtreaderParser()->GetPtreaderSplitData().size(), 1, 1));
186     } else {
187         EXPECT_TRUE(false);
188     }
189 }
190 
191 /**
192  * @tc.name: SplitFileDataByHtraceTest
193  * @tc.desc: Test htrace parsing binary file export database
194  * @tc.type: FUNC
195  */
196 HWTEST_F(SplitFileDataTest, SplitFileDataByEbpfTest, TestSize.Level1)
197 {
198     TS_LOGI("test43-3");
199     const std::string tracePath = "../../test/resource/ebpf_bio.htrace";
200     if (access(tracePath.c_str(), F_OK) == 0) {
201         auto ta = std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
202         ta->minTs_ = 800423789228;
203         ta->maxTs_ = 810586732842;
204         ParseData(ta, tracePath);
205         EXPECT_TRUE(CheckData(ta, tracePath));
206     } else {
207         EXPECT_TRUE(false);
208     }
209 }
210 
211 /**
212  * @tc.name: SplitFileDataByNativehookTest
213  * @tc.desc: Test htrace parsing binary file export database
214  * @tc.type: FUNC
215  */
216 HWTEST_F(SplitFileDataTest, SplitFileDataByNativehookTest, TestSize.Level1)
217 {
218     TS_LOGI("test43-4");
219     const std::string tracePath = "../../test/resource/Mmap.htrace";
220     ASSERT_EQ(access(tracePath.c_str(), F_OK), 0);
221 
222     auto ta = std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
223     ta->minTs_ = 1502031384794922107;
224     ta->maxTs_ = 1502031423412858932;
225     ParseData(ta, tracePath);
226     EXPECT_TRUE(CheckData(ta, tracePath));
227 }
228 
229 /**
230  * @tc.name: SplitFileDataByPerfTest
231  * @tc.desc: Test htrace parsing binary file export database
232  * @tc.type: FUNC
233  */
234 HWTEST_F(SplitFileDataTest, SplitFileDataByPerfTest, TestSize.Level1)
235 {
236     TS_LOGI("test43-5");
237     const std::string tracePath = "../../test/resource/hiprofiler_data_perf.htrace";
238     ASSERT_EQ(access(tracePath.c_str(), F_OK), 0);
239 
240     auto ta = std::make_unique<SysTuning::TraceStreamer::TraceStreamerSelector>();
241     ta->minTs_ = 30389799963682;
242     ta->maxTs_ = 30408971157414;
243     ParseData(ta, tracePath);
244     EXPECT_TRUE(CheckData(ta, tracePath));
245 }
246 
247 } // namespace TraceStreamer
248 } // namespace SysTuning
249