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