• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <chrono>
16 #include <fcntl.h>
17 #include <hwext/gtest-ext.h>
18 #include <hwext/gtest-tag.h>
19 #include <thread>
20 #include <unistd.h>
21 
22 #include "file_utils.h"
23 #include "ftrace_fs_ops.h"
24 #include "ftrace_parser.h"
25 #include "securec.h"
26 #include "sub_event_parser.h"
27 
28 using FTRACE_NS::EventFormat;
29 using FTRACE_NS::FtraceFsOps;
30 using FTRACE_NS::FtraceParser;
31 using FTRACE_NS::SubEventParser;
32 using testing::ext::TestSize;
33 
34 namespace {
35 #ifndef PAGE_SIZE
36 constexpr uint32_t PAGE_SIZE = 4096;
37 #endif
38 constexpr auto TEST_DELAY = std::chrono::milliseconds(10);
39 constexpr uint32_t SCHED_SWITCH_EVENT_ID = 189;
40 const std::string SCHED_SWITCH_FORMAT_DESC = R"(
41 name: sched_switch
42 ID: 189
43 format:
44         field:unsigned short common_type;       offset:0;       size:2; signed:0;
45         field:unsigned char common_flags;       offset:2;       size:1; signed:0;
46         field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
47         field:int common_pid;   offset:4;       size:4; signed:1;
48 
49         field:char prev_comm[16];       offset:8;       size:16;        signed:0;
50         field:pid_t prev_pid;   offset:24;      size:4; signed:1;
51         field:int prev_prio;    offset:28;      size:4; signed:1;
52         field:long prev_state;  offset:32;      size:4; signed:1;
53         field:char next_comm[16];       offset:36;      size:16;        signed:0;
54         field:pid_t next_pid;   offset:52;      size:4; signed:1;
55         field:int next_prio;    offset:56;      size:4; signed:1;
56 
57 print fmt: "prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", ...
58 )";
59 
60 class SubEventParserTest : public ::testing::Test {
61 protected:
SetUp()62     void SetUp() override
63     {
64         SubEventParser::GetInstance().idToFunctions_.clear();
65     }
66 
TearDown()67     void TearDown() override
68     {
69         SubEventParser::GetInstance().idToFunctions_.clear();
70     }
71 };
72 
73 /*
74  * @tc.name: IsSupportName
75  * @tc.desc: test SubEventParser::IsSupport with normal case.
76  * @tc.type: FUNC
77  */
78 HWTEST_F(SubEventParserTest, IsSupportName, TestSize.Level1)
79 {
80     EXPECT_FALSE(SubEventParser::GetInstance().IsSupport("xxx"));
81     EXPECT_TRUE(SubEventParser::GetInstance().IsSupport("sched_switch"));
82 }
83 
84 /*
85  * @tc.name: SetupEvent
86  * @tc.desc: test SubEventParser::SetupEvent with normal case.
87  * @tc.type: FUNC
88  */
89 HWTEST_F(SubEventParserTest, SetupEvent, TestSize.Level1)
90 {
91     EventFormat format;
92     FtraceParser ftraceParser;
93     format.eventType = "sched";
94     format.eventName = "sched_switch";
95     EXPECT_TRUE(ftraceParser.ParseEventFormat(SCHED_SWITCH_FORMAT_DESC, format));
96 
97     EXPECT_TRUE(nullptr == SubEventParser::GetInstance().GetParseEventCtx(format.eventId));
98     EXPECT_TRUE(SubEventParser::GetInstance().SetupEvent(format));
99     EXPECT_TRUE(nullptr != SubEventParser::GetInstance().GetParseEventCtx(format.eventId));
100 }
101 
102 /*
103  * @tc.name: IsSupportId
104  * @tc.desc: test SubEventParser::IsSupport with normal case.
105  * @tc.type: FUNC
106  */
107 HWTEST_F(SubEventParserTest, IsSupportId, TestSize.Level1)
108 {
109     EventFormat format;
110     FtraceParser ftraceParser;
111     format.eventType = "sched";
112     format.eventName = "sched_switch";
113     EXPECT_TRUE(ftraceParser.ParseEventFormat(SCHED_SWITCH_FORMAT_DESC, format));
114     SubEventParser::GetInstance().schedSwitchCtx = nullptr;
115     EXPECT_TRUE(nullptr == SubEventParser::GetInstance().GetParseEventCtx(format.eventId));
116     EXPECT_TRUE(SubEventParser::GetInstance().SetupEvent(format));
117     EXPECT_TRUE(nullptr != SubEventParser::GetInstance().GetParseEventCtx(format.eventId));
118 }
119 
120 /*
121  * @tc.name: ParseEvent
122  * @tc.desc: test SubEventParser::ParseEvent with normal case.
123  * @tc.type: FUNC
124  */
125 HWTEST_F(SubEventParserTest, ParseEvent, TestSize.Level1)
126 {
127     EventFormat format;
128     FtraceParser ftraceParser;
129     format.eventType = "sched";
130     format.eventName = "sched_switch";
131     EXPECT_TRUE(ftraceParser.ParseEventFormat(SCHED_SWITCH_FORMAT_DESC, format));
132     EXPECT_TRUE(SubEventParser::GetInstance().SetupEvent(format));
133     EXPECT_EQ(format.eventId, SCHED_SWITCH_EVENT_ID);
134 
135     std::vector<uint8_t> buffer(PAGE_SIZE, 0);
136     std::vector<uint8_t> zeros(PAGE_SIZE, 0);
137     std::string traceRaw = FtraceFsOps::GetInstance().GetRawTracePath(0);
138     int fd = open(traceRaw.c_str(), O_EXCL);
139     EXPECT_NE(fd, -1);
140 
141     EXPECT_TRUE(FtraceFsOps::GetInstance().ClearTraceBuffer());
142     EXPECT_TRUE(FtraceFsOps::GetInstance().EnableEvent("sched", "sched_switch"));
143     EXPECT_TRUE(FtraceFsOps::GetInstance().EnableTracing());
144 
145     std::this_thread::sleep_for(TEST_DELAY);
146     EXPECT_EQ(read(fd, buffer.data(), buffer.size()), static_cast<int>(PAGE_SIZE));
147     EXPECT_TRUE(FtraceFsOps::GetInstance().DisableTracing());
148     EXPECT_EQ(close(fd), 0);
149     EXPECT_NE(buffer, zeros);
150 
151     FtraceEvent event = {};
152     SubEventParser::ParseEventCtx* ctx = SubEventParser::GetInstance().GetParseEventCtx(format.eventId);
153     EXPECT_TRUE(ctx != nullptr);
154     SubEventParser::GetInstance().ParseEvent(event, buffer.data(), buffer.size(), ctx);
155 }
156 } // namespace
157