• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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