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 <thread>
17 #include <chrono>
18 #include <gtest/gtest.h>
19 #include "ffrt_inner.h"
20 #include "c/loop.h"
21 #define private public
22 #include "sync/poller.h"
23 #undef private
24 #include "util.h"
25 #include "../common.h"
26
27 using namespace std;
28 using namespace ffrt;
29 using namespace testing;
30 #ifdef HWTEST_TESTING_EXT_ENABLE
31 using namespace testing::ext;
32 #endif
33
34 class PollerTest : public testing::Test {
35 protected:
SetUpTestCase()36 static void SetUpTestCase()
37 {
38 }
39
TearDownTestCase()40 static void TearDownTestCase()
41 {
42 }
43
SetUp()44 virtual void SetUp()
45 {
46 }
47
TearDown()48 virtual void TearDown()
49 {
50 }
51 };
52
Testfun(void* data)53 static void Testfun(void* data)
54 {
55 int* testData = static_cast<int*>(data);
56 *testData += 1;
57 printf("%d, timeout callback\n", *testData);
58 }
59 static void (*g_cb)(void*) = Testfun;
60
61 /*
62 * 测试用例名称:poll_once_batch_timeout
63 * 测试用例描述:PollOnce批量超时测试
64 * 预置条件 :无
65 * 操作步骤 :1、调用注册接口
66 2、单次调用PollOnce
67 * 预期结果 :1、超时任务全部从队列中清除
68 2、当实际超时时间很长,但是传入超时时间很短,应该按传入时间执行
69 */
HWTEST_F(PollerTest, poll_once_batch_timeout, TestSize.Level1)70 HWTEST_F(PollerTest, poll_once_batch_timeout, TestSize.Level1)
71 {
72 Poller poller;
73 // 1、组装timeMap_
74 static int result0 = 0;
75 int* xf = &result0;
76 void* data = xf;
77 uint64_t timeout = 10;
78 uint64_t timeout1 = 11;
79 uint64_t timeout2 = 12;
80 uint64_t sleepTime = 25000;
81 poller.RegisterTimer(timeout, data, g_cb, false);
82 poller.RegisterTimer(timeout1, data, g_cb, false);
83 poller.RegisterTimer(timeout2, data, g_cb, false);
84 // 调用PollOnce,预计timerMap_为空,全部清除
85 usleep(sleepTime);
86 poller.PollOnce(1);
87 EXPECT_EQ(true, poller.DetermineEmptyMap());
88
89 uint64_t timeout3 = 10000;
90 uint64_t timeout4 = 100;
91 int loopNum = 2;
92 poller.RegisterTimer(timeout3, data, g_cb, false);
93 TimePoint start = std::chrono::steady_clock::now();
94 for (int i = 0; i < loopNum; ++i) {
95 poller.PollOnce(timeout4);
96 }
97 TimePoint end = std::chrono::steady_clock::now();
98 int m = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
99 // 预计等待时间为100,可能有几毫秒的误差
100 EXPECT_EQ(true, m >= timeout4 && m < timeout3);
101 }
102
103 /*
104 * 测试用例名称:cache_events_mask_test
105 * 测试用例描述:本地events缓存
106 * 预置条件 :无
107 * 操作步骤 :新增event缓存
108 * 预期结果 :task对应的events缓存内有没有新增
109 */
HWTEST_F(PollerTest, cache_events_mask_test, TestSize.Level1)110 HWTEST_F(PollerTest, cache_events_mask_test, TestSize.Level1)
111 {
112 Poller poller;
113 CPUEUTask* currTask;
114 EventVec eventVec;
115 epoll_event ev;
116 eventVec.push_back(ev);
117 poller.CacheEventsAndDoMask(currTask, eventVec);
118 EXPECT_EQ(1, poller.m_cachedTaskEvents[currTask].size());
119 }
120
121 /*
122 * 测试用例名称:fetch_cached_event_unmask
123 * 测试用例描述:遍历本地events缓存,并提出缓存event
124 * 预置条件 :无
125 * 操作步骤 :1、新增event缓存 2、清除缓存
126 * 预期结果 :task对应的events看有没有去除
127 */
HWTEST_F(PollerTest, fetch_cached_event_unmask, TestSize.Level1)128 HWTEST_F(PollerTest, fetch_cached_event_unmask, TestSize.Level1)
129 {
130 Poller poller;
131 CPUEUTask* currTask;
132 EventVec eventVec;
133 epoll_event ev;
134 struct epoll_event events[1024];
135 eventVec.push_back(ev);
136 poller.CacheEventsAndDoMask(currTask, eventVec);
137 int fdCnt = poller.FetchCachedEventAndDoUnmask(currTask, events);
138 EXPECT_EQ(1, fdCnt);
139 }
140 /*
141 * 测试用例名称:poll_once_batch_timeout
142 * 测试用例描述:PollOnce批量超时测试
143 * 预置条件 :无
144 * 操作步骤 :1、调用注册接口,注册repeat为true的timer
145 2、创建两个线程,并发PollerOnce和Unregister
146 * 预期结果 :1、任务全部从队列中清除
147 */
HWTEST_F(PollerTest, unregister_timer_001, TestSize.Level1)148 HWTEST_F(PollerTest, unregister_timer_001, TestSize.Level1)
149 {
150 Poller poller;
151 // 1、组装timeMap_
152 static int result0 = 0;
153 int* xf = &result0;
154 void* data = xf;
155 uint64_t timeout = 1;
156 uint64_t sleepTime = 2500;
157 int maxIter = 100;
158 // 2、 创建两个线程,并发PollerOnce和Unregister
159 for (int i = 0; i < maxIter; i++) {
160 int timerHandle = poller.RegisterTimer(timeout, data, g_cb, true);
161 EXPECT_FALSE(poller.timerMap_.empty());
162 auto boundPollonce = std::bind(&Poller::PollOnce, &poller, timeout);
163 auto boundUnregister = std::bind(&Poller::UnregisterTimer, &poller, timerHandle);
164 usleep(sleepTime);
165 std::thread thread1(boundPollonce);
166 std::thread thread2(boundUnregister);
167 thread1.join();
168 thread2.join();
169 EXPECT_TRUE(poller.timerMap_.empty());
170 EXPECT_TRUE(poller.executedHandle_.empty());
171 poller.timerMap_.clear();
172 poller.executedHandle_.clear();
173 }
174 }