1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 #include <fcntl.h>
16 #include <hwext/gtest-ext.h>
17 #include <hwext/gtest-tag.h>
18 #include <thread>
19 #include <unistd.h>
20
21 #include "flow_controller.h"
22 #include "ftrace_fs_ops.h"
23 #include "ftrace_parser.h"
24
25 using FTRACE_NS::FlowController;
26 using FTRACE_NS::FtraceFsOps;
27 using FTRACE_NS::FtraceParser;
28 using FTRACE_NS::PerCpuStats;
29 using testing::ext::TestSize;
30
31 namespace {
32 #ifndef PAGE_SIZE
33 constexpr uint32_t PAGE_SIZE = 4096;
34 #endif
35
36 constexpr uint32_t BUFFER_SIZE_KB = 256;
37 constexpr uint32_t FLUSH_INTERVAL_MS = 100;
38 constexpr uint32_t FLUSH_THRESHOLD_KB = 1024;
39 constexpr uint32_t TRACE_PERIOD_MS = 500;
40 using WriterStructPtr = std::unique_ptr<WriterStruct>::pointer;
41 using ConstVoidPtr = std::unique_ptr<const void>::pointer;
42
43 long WriteFunc(WriterStructPtr writer, ConstVoidPtr data, size_t size);
44 bool FlushFunc(WriterStructPtr writer);
45
46 class FtraceParserTest : public ::testing::Test {
47 protected:
SetUpTestCase()48 static void SetUpTestCase()
49 {
50 // start tracing sched_switch event
51 FlowController controller;
52 TracePluginConfig config;
53
54 // set writer
55 WriterStruct writer = {WriteFunc, FlushFunc};
56 controller.SetWriter(static_cast<WriterStructPtr>(&writer));
57
58 // set config
59 config.add_ftrace_events("sched/sched_switch");
60 config.set_buffer_size_kb(BUFFER_SIZE_KB);
61 config.set_flush_interval_ms(FLUSH_INTERVAL_MS);
62 config.set_flush_threshold_kb(FLUSH_THRESHOLD_KB);
63 config.set_parse_ksyms(true);
64 config.set_clock("global");
65 config.set_trace_period_ms(TRACE_PERIOD_MS);
66 config.set_raw_data_prefix("/data/local/tmp/raw_trace_");
67 std::vector<uint8_t> configData(config.ByteSizeLong());
68 config.SerializeToArray(configData.data(), configData.size());
69 controller.LoadConfig(configData.data(), configData.size());
70 controller.StartCapture();
71 controller.StopCapture();
72 }
73
SetUp()74 void SetUp() override {}
TearDown()75 void TearDown() override {}
76 };
77
WriteFunc(WriterStructPtr writer,ConstVoidPtr data,size_t size)78 long WriteFunc(WriterStructPtr writer, ConstVoidPtr data, size_t size)
79 {
80 if (writer == nullptr || data == nullptr || size <= 0) {
81 return -1;
82 }
83
84 return 0;
85 }
86
FlushFunc(WriterStructPtr writer)87 bool FlushFunc(WriterStructPtr writer)
88 {
89 if (writer == nullptr) {
90 return false;
91 }
92 return true;
93 }
94
95 /*
96 * @tc.name: Init
97 * @tc.desc: test FtraceParser::Init with normal case.
98 * @tc.type: FUNC
99 */
100 HWTEST_F(FtraceParserTest, Init, TestSize.Level1)
101 {
102 FtraceParser parser;
103 EXPECT_TRUE(parser.Init());
104 }
105
106 /*
107 * @tc.name: SetupEvent
108 * @tc.desc: test FtraceParser::Init with normal case.
109 * @tc.type: FUNC
110 */
111 HWTEST_F(FtraceParserTest, SetupEvent, TestSize.Level1)
112 {
113 FtraceParser parser;
114 EXPECT_TRUE(parser.SetupEvent("sched", "sched_switch"));
115 }
116
117 /*
118 * @tc.name: ParseSavedTgid
119 * @tc.desc: test FtraceParser::ParseSavedTgid with normal case.
120 * @tc.type: FUNC
121 */
122 HWTEST_F(FtraceParserTest, ParseSavedTgid, TestSize.Level1)
123 {
124 FtraceParser parser;
125 EXPECT_TRUE(parser.ParseSavedTgid(FtraceFsOps::GetInstance().GetSavedTgids()));
126 }
127
128 /*
129 * @tc.name: ParseSavedCmdlines
130 * @tc.desc: test FtraceParser::ParseSavedCmdlines with normal case.
131 * @tc.type: FUNC
132 */
133 HWTEST_F(FtraceParserTest, ParseSavedCmdlines, TestSize.Level1)
134 {
135 FtraceParser parser;
136 EXPECT_TRUE(parser.ParseSavedCmdlines(FtraceFsOps::GetInstance().GetSavedCmdLines()));
137 }
138
139 /*
140 * @tc.name: ParsePerCpuStatus
141 * @tc.desc: test FtraceParser::ParsePerCpuStatus with normal case.
142 * @tc.type: FUNC
143 */
144 HWTEST_F(FtraceParserTest, ParsePerCpuStatus, TestSize.Level1)
145 {
146 FtraceParser parser;
147 PerCpuStats perCpuStats = {};
148 EXPECT_FALSE(parser.ParsePerCpuStatus(perCpuStats, ""));
149
150 std::string perCpuStatsStr = FtraceFsOps::GetInstance().GetPerCpuStats(0);
151 EXPECT_TRUE(parser.ParsePerCpuStatus(perCpuStats, perCpuStatsStr));
152 }
153
154 /*
155 * @tc.name: ParsePage
156 * @tc.desc: test SubEventParser::ParsePage with normal case.
157 * @tc.type: FUNC
158 */
159 HWTEST_F(FtraceParserTest, ParsePage, TestSize.Level1)
160 {
161 std::vector<uint8_t> buffer(PAGE_SIZE, 0);
162 std::string traceRaw = FtraceFsOps::GetInstance().GetRawTracePath(0);
163 int fd = open(traceRaw.c_str(), O_EXCL);
164 EXPECT_NE(fd, -1);
165
166 EXPECT_TRUE(FtraceFsOps::GetInstance().ClearTraceBuffer());
167 EXPECT_TRUE(FtraceFsOps::GetInstance().EnableEvent("sched", "sched_switch"));
168 EXPECT_TRUE(FtraceFsOps::GetInstance().EnableTracing());
169 std::this_thread::yield();
170 EXPECT_EQ(read(fd, buffer.data(), buffer.size()), PAGE_SIZE);
171 EXPECT_TRUE(FtraceFsOps::GetInstance().DisableTracing());
172
173 FtraceCpuDetailMsg cpuDetailMsg = {};
174 FtraceParser parser;
175 EXPECT_TRUE(parser.ParsePage(cpuDetailMsg, buffer.data(), buffer.size()));
176 EXPECT_EQ(close(fd), 0);
177 }
178 } // namespace