• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cinttypes>
16 #include <fstream>
17 #include <gtest/gtest.h>
18 #include <random>
19 #include <string>
20 
21 #include "logging.h"
22 #include "printk_formats_parser.h"
23 
24 using FTRACE_NS::PrintkFormatsParser;
25 using namespace testing::ext;
26 namespace {
27 constexpr int ROUNDS = 20;
28 constexpr int ADDR_MAX_SIZE = 8;
29 constexpr int SYMBOL_MAX_SIZE = 16;
30 constexpr int HEX_BASE = 16;
31 
32 constexpr char RANDOM_HEX_TABLE[] = "0123456789ABCDEF";
33 constexpr long RANDOM_HEX_NUMBER = std::size(RANDOM_HEX_TABLE) - 1;
34 constexpr char RANDOM_CHAR_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
35 constexpr long RANDOM_CHAR_NUMBER = std::size(RANDOM_CHAR_TABLE) - 1;
36 
37 constexpr uint64_t CPU_ON_ADDR = 0xc0b01947;
38 const std::string CPU_ON_STR = "CPU_ON";
39 const std::string NORMAL_PRINTK_FORMATS = R"(
40 0xc0aff2a9 : "CPU wakeup interrupts"
41 0xc0aff2bf : "Timer broadcast interrupts"
42 0xc0aff2da : "Rescheduling interrupts"
43 0xc0aff2f2 : "Function call interrupts"
44 0xc0aff30b : "CPU stop interrupts"
45 0xc0aff31f : "IRQ work interrupts"
46 0xc0aff333 : "completion interrupts"
47 0xc0b018e0 : "CPU_OFF"
48 0xc0b01947 : "CPU_ON"
49 0xc0b068a6 : "thaw_processes"
50 0xc0b068a6 : "thaw_processes"
51 0xc0b06a3a : "resume_console"
52 0xc0b06a3a : "resume_console"
53 0xc0b06b38 : "machine_suspend"
54 0xc0b06b38 : "machine_suspend"
55 0xc0b06b38 : "machine_suspend"
56 0xc0b06b38 : "machine_suspend"
57 0xc0b06b48 : "suspend_enter"
58 0xc0b06b56 : "sync_filesystems"
59 0xc0b06b56 : "sync_filesystems"
60 0xc0b06b48 : "suspend_enter"
61 0xc0b06b86 : "freeze_processes"
62 0xc0b06b86 : "freeze_processes"
63 0xc0e18840 : "rcu_sched"
64 0xc0e18b00 : "rcu_bh"
65 0xc0b08096 : "Start context switch"
66 0xc0b080ab : "End context switch"
67 0xc0b08144 : "Start scheduler-tick"
68 0xc0b08159 : "End scheduler-tick"
69 0xc0b0817e : "Startleaf"
70 0xc0b08188 : "Prestarted"
71 0xc0b08193 : "Startedleaf"
72 0xc0b0819f : "Startedleafroot"
73 0xc0b081af : "Startedroot"
74 0xc0b081bb : "NoGPkthread"
75 0xc0b6a70d : "Begin"
76 0xc0b084b7 : "EarlyExit"
77 0xc0b084c1 : "Inc1"
78 0xc0b084c6 : "OfflineNoCB"
79 0xc0b084d2 : "OnlineNoCB"
80 0xc0b084dd : "OnlineQ"
81 0xc0b084e5 : "OnlineNQ"
82 0xc0b084ee : "Inc2"
83 0xc0b0850c : "LastCB"
84 0xc0b084cf : "CB"
85 0xc0b01ebb : "IRQ"
86 0xc0b08513 : "IRQNQ"
87 0xc0b0868a : "CleanupMore"
88 0xc0b0868a : "CleanupMore"
89 0xc0b08696 : "Cleanup"
90 0xc0b0879f : "Start RCU core"
91 0xc0b087ae : "End RCU core"
92 )";
93 
94 class PrintkFormatsParserTest : public ::testing::Test {
95     std::mt19937 gen_;
96 
97 protected:
SetUp()98     void SetUp() override
99     {
100         PrintkFormatsParser::GetInstance().printkFormats_.clear();
101     }
102 
TearDown()103     void TearDown() override
104     {
105         PrintkFormatsParser::GetInstance().printkFormats_.clear();
106     }
107 
RandomInt(int a,int b)108     int RandomInt(int a, int b)
109     {
110         std::uniform_int_distribution<int> distrib(a, b);
111         return distrib(gen_);
112     }
113 
RandomChar()114     char RandomChar()
115     {
116         return RANDOM_CHAR_TABLE[RandomInt(0, RANDOM_CHAR_NUMBER - 1)];
117     }
118 
RandomHex()119     char RandomHex()
120     {
121         return RANDOM_HEX_TABLE[RandomInt(0, RANDOM_HEX_NUMBER - 1)];
122     }
123 
RandomAddr(int len)124     std::string RandomAddr(int len)
125     {
126         std::string str = "0x0";
127         str.reserve(str.size() + len);
128         for (int i = 0; i < len; i++) {
129             str.push_back(RandomHex());
130         }
131         return str;
132     }
133 
RandomString(int len)134     std::string RandomString(int len)
135     {
136         std::string str;
137         str.reserve(len);
138         for (int i = 0; i < len; i++) {
139             str.push_back(RandomChar());
140         }
141         return str;
142     }
143 
BuildPrintkLine(std::string randNumber,std::string randomString)144     std::string BuildPrintkLine(std::string randNumber, std::string randomString)
145     {
146         std::string str = randNumber + " : " + randomString;
147         return str;
148     }
149 };
150 
151 /*
152  * @tc.name: false PrintkFormatsParser size
153  * @tc.desc: test PrintkFormatsParser::PrintkFormatsParser with false case
154  * @tc.type: FUNC
155  */
156 HWTEST_F(PrintkFormatsParserTest, PrintkFormatsParserFalse, TestSize.Level1)
157 {
158     std::string input = "test";
159     EXPECT_FALSE(PrintkFormatsParser::GetInstance().Parse(input));
160 
161     std::string symbol = PrintkFormatsParser::GetInstance().GetSymbol(0);
162     EXPECT_EQ(symbol, "NULL");
163 }
164 
165 /*
166  * @tc.name: normal PrintkFormatsParser size
167  * @tc.desc: test PrintkFormatsParser:: normal with normal case.
168  * @tc.type: FUNC
169  */
170 HWTEST_F(PrintkFormatsParserTest, PrintkFormatsParserNormal, TestSize.Level1)
171 {
172     EXPECT_TRUE(PrintkFormatsParser::GetInstance().Parse(NORMAL_PRINTK_FORMATS));
173 
174     for (auto& entry : PrintkFormatsParser::GetInstance().printkFormats_) {
175         uint64_t addr = entry.first;
176         std::string symbol = entry.second;
177         PROFILER_LOG_INFO(LOG_CORE, "%" PRIx64 " : %s", addr, symbol.c_str());
178     }
179     std::string symbol = PrintkFormatsParser::GetInstance().GetSymbol(CPU_ON_ADDR);
180     EXPECT_EQ(symbol, CPU_ON_STR);
181 }
182 
183 /*
184  * @tc.name: normal PrintkFormatsParser size
185  * @tc.desc: test PrintkFormatsParser:: normal with Symbols case.
186  * @tc.type: FUNC
187  */
188 HWTEST_F(PrintkFormatsParserTest, PrintkFormatsParserSymbolsNormal, TestSize.Level1)
189 {
190     std::string input = "1 : \"test\"";
191     EXPECT_NE(input, "");
192 
193     EXPECT_TRUE(PrintkFormatsParser::GetInstance().Parse(input));
194 
195     std::string symbol = PrintkFormatsParser::GetInstance().GetSymbol(1);
196     EXPECT_EQ(symbol, "test");
197 }
198 
199 /*
200  * @tc.name: rand PrintkFormatsParser size
201  * @tc.desc: test PrintkFormatsParser:: normal with rand case.
202  * @tc.type: FUNC
203  */
204 HWTEST_F(PrintkFormatsParserTest, PrintkFormatsParserNormalRand, TestSize.Level1)
205 {
206     for (int i = 0; i < ROUNDS; i++) {
207         // 组成
208         std::string addr = RandomAddr(RandomInt(1, ADDR_MAX_SIZE));
209         std::string symbol = RandomString(RandomInt(1, SYMBOL_MAX_SIZE));
210         std::string line = BuildPrintkLine(addr, symbol);
211         EXPECT_TRUE(PrintkFormatsParser::GetInstance().Parse(line));
212 
213         std::string symbolGot = PrintkFormatsParser::GetInstance().GetSymbol(strtoull(addr.c_str(), nullptr, HEX_BASE));
214         EXPECT_EQ(symbolGot, symbol);
215     }
216 }
217 } // namespace