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 <fstream>
16 #include <hwext/gtest-ext.h>
17 #include <hwext/gtest-tag.h>
18 #include <random>
19 #include <string>
20
21 #include "kernel_symbols_parser.h"
22
23 using FTRACE_NS::KernelSymbol;
24 using FTRACE_NS::KernelSymbolsParser;
25 using namespace testing::ext;
26 namespace {
27 constexpr int ROUNDS = 20;
28 constexpr int STR_MAX_SIZE = 10;
29 constexpr int NUM_BEGIN_PLACE = 10000000;
30 constexpr char RANDOM_CHAR_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31 constexpr long RANDOM_CHAR_NUMBER = std::size(RANDOM_CHAR_TABLE) - 1; // ignore '\0'
32
33 class KernelSymbolsParserTest : public ::testing::Test {
34 std::mt19937 gen_;
35
36 protected:
SetUp()37 void SetUp() override {}
38
TearDown()39 void TearDown() override {}
40
RandomInt(int a,int b)41 int RandomInt(int a, int b)
42 {
43 std::uniform_int_distribution<int> distrib(a, b);
44 return distrib(gen_);
45 }
46
RandomChar()47 char RandomChar()
48 {
49 return RANDOM_CHAR_TABLE[RandomInt(0, RANDOM_CHAR_NUMBER - 1)];
50 }
RandomNumber()51 int RandomNumber()
52 {
53 return RandomInt(1, NUM_BEGIN_PLACE);
54 }
55
RandAddr()56 std::string RandAddr()
57 {
58 std::string str = std::to_string(RandomNumber());
59 return str;
60 }
61
RandomName(int len,bool suffix)62 std::string RandomName(int len, bool suffix)
63 {
64 std::string str;
65 str.reserve(len + 1);
66 for (int i = 0; i < (len + 1); i++) {
67 str.push_back(RandomChar());
68 }
69 if (suffix) {
70 str + ".cfi";
71 }
72 return str;
73 }
74
RandomType()75 char RandomType()
76 {
77 char str = 't';
78 if (RandomInt(0, 1) == 0) {
79 str = 'T';
80 }
81 return str;
82 }
83
RandomSymbols(std::string randAddr,char randomType,std::string RandomName)84 std::string RandomSymbols(std::string randAddr, char randomType, std::string RandomName)
85 {
86 std::string str = randAddr + " " + randomType + " " + RandomName;
87 return str;
88 }
89 };
90
visitor(const KernelSymbol & kernelSymbol)91 void visitor(const KernelSymbol& kernelSymbol)
92 {
93 uint64_t addr = kernelSymbol.addr;
94 char type = kernelSymbol.type;
95 std::string name = kernelSymbol.name;
96 if (addr > 0 && type > 0) {
97 }
98 }
99
100 /*
101 * @tc.name: normal KernelSymbolParser size
102 * @tc.desc: test KernelSymbolParser:: normal with normal case.
103 * @tc.type: FUNC
104 */
105 HWTEST_F(KernelSymbolsParserTest, KernelSymbolsParserSingle, TestSize.Level1)
106 {
107 std::unique_ptr<KernelSymbolsParser> kernelSymbols = std::make_unique<KernelSymbolsParser>();
108 EXPECT_NE(kernelSymbols, nullptr);
109
110 kernelSymbols->Accept(visitor);
111
112 std::string symbols = "1 T name.cfi";
113 EXPECT_TRUE(kernelSymbols->Parse(symbols));
114 }
115
116 /*
117 * @tc.name: normal KernelSymbolsParser size
118 * @tc.desc: test KernelSymbolsParser:: normal with normal case.
119 * @tc.type: FUNC
120 */
121 HWTEST_F(KernelSymbolsParserTest, KernelSymbolsParserNormalMulti, TestSize.Level1)
122 {
123 std::unique_ptr<KernelSymbolsParser> kernelSymbols = std::make_unique<KernelSymbolsParser>();
124 EXPECT_NE(kernelSymbols, nullptr);
125
126 kernelSymbols->Accept(visitor);
127
128 std::string symbols = "1 T name1.cfi\n2 t name2.cfi\n3 T name3.cfi\n4 t name4.cfi";
129 EXPECT_TRUE(kernelSymbols->Parse(symbols));
130 }
131
132 /*
133 * @tc.name: normal KernelSymbolsParser size
134 * @tc.desc: test KernelSymbolsParser::KernelSymbolsParser with false case.
135 * @tc.type: FUNC
136 */
137 HWTEST_F(KernelSymbolsParserTest, KernelSymbolsParserNormalFalse, TestSize.Level1)
138 {
139 std::unique_ptr<KernelSymbolsParser> kernelSymbols = std::make_unique<KernelSymbolsParser>();
140 EXPECT_NE(kernelSymbols, nullptr);
141
142 kernelSymbols->Accept(visitor);
143
144 std::string symbols = "0 T name1.cfi\n2 a name2.cfi\n3 T $name3.cfi\n0 t name4.cfi\n4 t .cfi";
145 EXPECT_FALSE(kernelSymbols->Parse(symbols));
146 }
147
148 /*
149 * @tc.name: normal KernelSymbolsParser
150 * @tc.desc: test KernelSymbolsParser::KernelSymbolsParser with other case.
151 * @tc.type: FUNC
152 */
153 HWTEST_F(KernelSymbolsParserTest, KernelSymbolsParserNormalOther, TestSize.Level1)
154 {
155 std::unique_ptr<KernelSymbolsParser> kernelSymbols = std::make_unique<KernelSymbolsParser>();
156 EXPECT_NE(kernelSymbols, nullptr);
157
158 kernelSymbols->Accept(visitor);
159
160 std::string symbolsName = "1 T nameA\n1 T nameB\n1 T nameC\n1 T nameD\n";
161 EXPECT_TRUE(kernelSymbols->Parse(symbolsName));
162
163 std::string symbolsNameType = "2 t name\n2 T name\n2 t name\n2 T name\n";
164 EXPECT_TRUE(kernelSymbols->Parse(symbolsNameType));
165 }
166
167 /*
168 * @tc.name: rand KernelSymbolsParser size
169 * @tc.desc: test KernelSymbolsParser:: normal with rand case.
170 * @tc.type: FUNC
171 */
172 HWTEST_F(KernelSymbolsParserTest, KernelSymbolsParserNormalRand, TestSize.Level1)
173 {
174 for (int i = 0; i < ROUNDS; i++) {
175 // 组成
176 std::string randAddr = RandAddr();
177 char randomType = RandomType();
178 std::string randomName = RandomName(RandomInt(1, STR_MAX_SIZE), true);
179 std::string randomSymbols = RandomSymbols(randAddr, randomType, randomName);
180
181 std::unique_ptr<KernelSymbolsParser> kernelSymbols = std::make_unique<KernelSymbolsParser>();
182 EXPECT_NE(kernelSymbols, nullptr);
183
184 kernelSymbols->Accept(visitor);
185 EXPECT_TRUE(kernelSymbols->Parse(randomSymbols));
186 }
187 }
188 } // namespace