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