1 /*
2 * Copyright (c) 2025 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
16 #include <gtest/gtest.h>
17 #include <gtest/hwext/gtest-multithread.h>
18
19 #include <string>
20 #include <thread>
21 #include <unistd.h>
22
23 #include "dfx_define.h"
24 #include "dfx_test_util.h"
25 #include "kernel_stack_async_collector.h"
26
27 using namespace testing;
28 using namespace testing::ext;
29 using namespace testing::mt;
30
31 namespace OHOS {
32 namespace HiviewDFX {
33 std::atomic<int> g_count = 0;
34 class KernelStackAsyncCollectorTest : public testing::Test {
35 public:
SetUpTestCase()36 static void SetUpTestCase() {};
TearDownTestCase()37 static void TearDownTestCase() {};
SetUp()38 void SetUp() {};
TearDown()39 void TearDown() {};
40 };
41
42 /**
43 * @tc.name: KernelStackAsyncCollectorTest001
44 * @tc.desc: test KernelStackAsyncCollectorTest NotifyStartCollect interface
45 * @tc.type: FUNC
46 */
47 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest001, TestSize.Level0)
48 {
49 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest001: start.";
50 std::string res = ExecuteCommands("uname");
51 bool isSuccess = res.find("Linux") == std::string::npos;
52 if (!isSuccess) {
53 ASSERT_FALSE(isSuccess);
54 } else {
55 KernelStackAsyncCollector stackCollector;
56 pid_t tid = gettid();
57 ASSERT_TRUE(stackCollector.NotifyStartCollect(tid));
58 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetCollectedStackResult();
59 ASSERT_NE(stack.errorCode, KernelStackAsyncCollector::STACK_SUCCESS);
60 ASSERT_TRUE(stack.msg.empty());
61 sleep(1);
62 stack = stackCollector.GetCollectedStackResult();
63 ASSERT_EQ(stack.errorCode, KernelStackAsyncCollector::STACK_SUCCESS);
64 ASSERT_TRUE(stack.msg.find(std::to_string(tid)) != std::string::npos);
65 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest001: end.";
66 }
67 }
68
69 /**
70 * @tc.name: KernelStackAsyncCollectorTest002
71 * @tc.desc: test KernelStackAsyncCollectorTest NotifyStartCollect interface
72 * @tc.type: FUNC
73 */
74 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest002, TestSize.Level2)
75 {
76 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest002: start.";
77 std::string res = ExecuteCommands("uname");
78 bool isSuccess = res.find("Linux") == std::string::npos;
79 if (!isSuccess) {
80 ASSERT_FALSE(isSuccess);
81 } else {
82 KernelStackAsyncCollector stackCollector;
83 pid_t tid = gettid();
84 int waitTime = 0;
85 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetProcessStackWithTimeout(tid, waitTime);
86 ASSERT_NE(stack.errorCode, KernelStackAsyncCollector::STACK_SUCCESS);
87 ASSERT_TRUE(stack.msg.empty());
88
89 waitTime = 1000; // 1000 : 1000ms
90 stack = stackCollector.GetProcessStackWithTimeout(tid, waitTime);
91 ASSERT_EQ(stack.errorCode, KernelStackAsyncCollector::STACK_SUCCESS);
92 ASSERT_TRUE(stack.msg.find(std::to_string(tid)) != std::string::npos);
93 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest002: end.";
94 }
95 }
96
NotifyCollectStackTest()97 static void NotifyCollectStackTest()
98 {
99 KernelStackAsyncCollector stackCollector;
100 pid_t tid = gettid();
101 if (stackCollector.NotifyStartCollect(tid)) {
102 sleep(1);
103 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetCollectedStackResult();
104 ASSERT_EQ(stack.errorCode, KernelStackAsyncCollector::STACK_SUCCESS);
105 ASSERT_TRUE(stack.msg.find(std::to_string(tid)) != std::string::npos);
106 g_count++;
107 }
108 }
109
CollectStackWithTimeoutTest()110 static void CollectStackWithTimeoutTest()
111 {
112 constexpr int waitTime = 1000; // 1000 : 1000ms
113 pid_t tid = gettid();
114 KernelStackAsyncCollector stackCollector;
115 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetProcessStackWithTimeout(tid, waitTime);
116 if (stack.errorCode == KernelStackAsyncCollector::STACK_SUCCESS) {
117 ASSERT_TRUE(stack.msg.find(std::to_string(tid)) != std::string::npos);
118 g_count++;
119 }
120 }
121
122 /**
123 * @tc.name: KernelStackAsyncCollectorTest003
124 * @tc.desc: test KernelStackAsyncCollectorTest NotifyStartCollect interface
125 * @tc.type: FUNC
126 */
127 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest003, TestSize.Level2)
128 {
129 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest003: start.";
130 std::string res = ExecuteCommands("uname");
131 bool isSuccess = res.find("Linux") == std::string::npos;
132 if (!isSuccess) {
133 ASSERT_FALSE(isSuccess);
134 } else {
135 int threadCount = 3;
136 SET_THREAD_NUM(threadCount);
137 GTEST_RUN_TASK(NotifyCollectStackTest);
138 sleep(2); // 2 : 2s
139 ASSERT_EQ(g_count, threadCount);
140 threadCount = 10;
141 SET_THREAD_NUM(threadCount);
142 g_count = 0;
143 GTEST_RUN_TASK(NotifyCollectStackTest);
144 ASSERT_LT(g_count, threadCount);
145 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest003: end.";
146 }
147 }
148
149 /**
150 * @tc.name: KernelStackAsyncCollectorTest004
151 * @tc.desc: test KernelStackAsyncCollectorTest GetProcessStackWithTimeout interface
152 * @tc.type: FUNC
153 */
154 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest004, TestSize.Level2)
155 {
156 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest004: start.";
157 std::string res = ExecuteCommands("uname");
158 bool isSuccess = res.find("Linux") == std::string::npos;
159 if (!isSuccess) {
160 ASSERT_FALSE(isSuccess);
161 } else {
162 g_count = 0;
163 int threadCount = 3;
164 SET_THREAD_NUM(threadCount);
165 GTEST_RUN_TASK(CollectStackWithTimeoutTest);
166 sleep(2); // 2 : 2s
167 ASSERT_EQ(g_count, threadCount);
168 threadCount = 10;
169 SET_THREAD_NUM(threadCount);
170 g_count = 0;
171 GTEST_RUN_TASK(CollectStackWithTimeoutTest);
172 ASSERT_LT(g_count, threadCount);
173 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest004: end.";
174 }
175 }
176
177 /**
178 * @tc.name: KernelStackAsyncCollectorTest005
179 * @tc.desc: test KernelStackAsyncCollectorTest NotifyStartCollect interface in abnormal case
180 * @tc.type: FUNC
181 */
182 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest005, TestSize.Level2)
183 {
184 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest005: start.";
185 std::string res = ExecuteCommands("uname");
186 bool isSuccess = res.find("Linux") == std::string::npos;
187 if (!isSuccess) {
188 ASSERT_FALSE(isSuccess);
189 } else {
190 KernelStackAsyncCollector stackCollector;
191 pid_t tid = 0;
192 ASSERT_TRUE(stackCollector.NotifyStartCollect(tid));
193 sleep(1); // 1 : 1s
194 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetCollectedStackResult();
195 ASSERT_EQ(stack.errorCode, KernelStackAsyncCollector::STACK_NO_PROCESS);
196 ASSERT_TRUE(stack.msg.empty());
197 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest005: end.";
198 }
199 }
200
201 /**
202 * @tc.name: KernelStackAsyncCollectorTest006
203 * @tc.desc: test KernelStackAsyncCollectorTest GetProcessStackWithTimeout interface in abnormal case
204 * @tc.type: FUNC
205 */
206 HWTEST_F(KernelStackAsyncCollectorTest, KernelStackAsyncCollectorTest006, TestSize.Level2)
207 {
208 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest006: start.";
209 std::string res = ExecuteCommands("uname");
210 bool isSuccess = res.find("Linux") == std::string::npos;
211 if (!isSuccess) {
212 ASSERT_FALSE(isSuccess);
213 } else {
214 KernelStackAsyncCollector stackCollector;
215 int waitTime = 1000; // 1000 : 1000ms
216 KernelStackAsyncCollector::KernelResult stack = stackCollector.GetProcessStackWithTimeout(0, waitTime);
217 ASSERT_EQ(stack.errorCode, KernelStackAsyncCollector::STACK_NO_PROCESS);
218 ASSERT_TRUE(stack.msg.empty());
219 GTEST_LOG_(INFO) << "KernelStackAsyncCollectorTest006: end.";
220 }
221 }
222 } // namespace HiviewDFX
223 } // namepsace OHOS