1 /*
2  * Copyright (c) 2023 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 "ffrt_inner.h"
18 #include "dfx/bbox/bbox.h"
19 #include "c/queue_ext.h"
20 #include "../common.h"
21 
22 using namespace ffrt;
23 
24 extern void SaveTheBbox();
25 
26 using namespace testing;
27 #ifdef HWTEST_TESTING_EXT_ENABLE
28 using namespace testing::ext;
29 #endif
30 
31 class DfxTest : public testing::Test {
32 protected:
SetUpTestCase()33     static void SetUpTestCase()
34     {
35     }
36 
TearDownTestCase()37     static void TearDownTestCase()
38     {
39     }
40 
SetUp()41     virtual void SetUp()
42     {
43     }
44 
TearDown()45     virtual void TearDown()
46     {
47     }
48 };
49 
HWTEST_F(DfxTest, bboxtest, TestSize.Level1)50 HWTEST_F(DfxTest, bboxtest, TestSize.Level1)
51 {
52     SaveTheBbox();
53 }
54 
HWTEST_F(DfxTest, tracetest, TestSize.Level1)55 HWTEST_F(DfxTest, tracetest, TestSize.Level1)
56 {
57     int x = 0;
58     ffrt::submit(
59         [&]() {
60             ffrt::set_trace_tag("task");
61             x++;
62             ffrt::clear_trace_tag();
63         }, {}, {});
64     ffrt::wait();
65     EXPECT_EQ(x, 1);
66 }
67 
68 static struct sigaction s_oldSa[SIGSYS + 1]; // SIGSYS = 31
69 
SignalHandler(int signo, siginfo_t* info, void* context __attribute__((unused)))70 static void SignalHandler(int signo, siginfo_t* info, void* context __attribute__((unused)))
71 {
72     SaveTheBbox();
73 
74     // we need to deregister our signal handler for that signal before continuing.
75     sigaction(signo, &s_oldSa[signo], nullptr);
76 }
77 
SignalReg(int signo)78 static void SignalReg(int signo)
79 {
80     sigaction(signo, nullptr, &s_oldSa[signo]);
81     struct sigaction newAction;
82     newAction.sa_flags = SA_RESTART | SA_SIGINFO;
83     newAction.sa_sigaction = SignalHandler;
84     sigaction(signo, &newAction, nullptr);
85 }
86 
HWTEST_F(DfxTest, queue_dfx_bbox_normal_task_0001, TestSize.Level1)87 HWTEST_F(DfxTest, queue_dfx_bbox_normal_task_0001, TestSize.Level1)
88 {
89     // 异常信号用例,测试bbox功能正常;
90     int x = 0;
91     ffrt::mutex lock;
92 
93     pid_t pid = fork();
94     if (!pid) {
95         printf("pid = %d, thread id= %d  start\n", getpid(), pid);
96 
97         auto basic1Func = [&]() {
98             lock.lock();
99             ffrt_usleep(2000);
100             x = x + 1;
101             lock.unlock();
102         };
103 
104         auto basic2Func = [&]() {
105             ffrt_usleep(3000);
106             SignalReg(SIGABRT);
107             raise(SIGABRT);  // 向自身进程发送SIGABR
108         };
109 
110         auto basic3Func = [&]() {
111             ffrt_usleep(5000);
112             x = x + 1;
113         };
114 
115         for (int i = 0; i < 20; i++) {
116             ffrt::submit(basic1Func, {}, {}, ffrt::task_attr().qos(static_cast<int>(ffrt::qos_default)));
117         }
118         for (int i = 0; i < 10; i++) {
119             ffrt::submit(basic3Func, {}, {}, ffrt::task_attr().qos(static_cast<int>(ffrt::qos_default)));
120         }
121         auto task = ffrt::submit_h(basic2Func, {}, {}, ffrt::task_attr().qos(static_cast<int>(ffrt::qos_background)));
122 
123         ffrt::wait({task});
124         printf("pid = %d, thread id= %d  end\n", getpid(), pid);
125         exit(0);
126     }
127     sleep(1);
128 }
129 
HWTEST_F(DfxTest, queue_dfx_bbox_queue_task_0001, TestSize.Level1)130 HWTEST_F(DfxTest, queue_dfx_bbox_queue_task_0001, TestSize.Level1)
131 {
132     // 异常信号用例,测试bbox功能正常;
133     int x = 0;
134     ffrt::mutex lock;
135 
136     pid_t pid = fork();
137     if (!pid) {
138         printf("pid = %d, thread id= %d  start\n", getpid(), pid);
139         ffrt_queue_attr_t queue_attr;
140         ffrt_queue_attr_t queue_attr2;
141         (void)ffrt_queue_attr_init(&queue_attr); // 初始化属性,必须
142         ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
143         (void)ffrt_queue_attr_init(&queue_attr2); // 初始化属性,必须
144         ffrt_queue_t queue_handle2 = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr2);
145         std::function<void()> basic1Func = [&]() {
146             lock.lock();
147             ffrt_usleep(5000);
148             x = x + 1;
149             lock.unlock();
150         };
151 
152         auto basic3Func = [&]() {
153             lock.lock();
154             sleep(2);
155             lock.unlock();
156         };
157 
158         auto task = ffrt::submit_h(basic3Func, {}, {}, ffrt::task_attr().qos(static_cast<int>(ffrt::qos_background)));
159         ffrt_queue_submit(queue_handle, create_function_wrapper(basic1Func, ffrt_function_kind_queue), nullptr);
160         ffrt_queue_submit(queue_handle2, create_function_wrapper(basic1Func, ffrt_function_kind_queue), nullptr);
161 
162         SaveTheBbox();
163         ffrt::wait({task});
164         ffrt_queue_attr_destroy(&queue_attr);
165         ffrt_queue_destroy(queue_handle);
166         ffrt_queue_attr_destroy(&queue_attr2);
167         ffrt_queue_destroy(queue_handle2);
168         printf("pid = %d, thread id= %d  end\n", getpid(), pid);
169         exit(0);
170     }
171     sleep(1);
172 }
173