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 }