1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include <thread>
17484543d1Sopenharmony_ci#include <chrono>
18484543d1Sopenharmony_ci#include <gtest/gtest.h>
19484543d1Sopenharmony_ci#include "ffrt_inner.h"
20484543d1Sopenharmony_ci#include "c/loop.h"
21484543d1Sopenharmony_ci#define private public
22484543d1Sopenharmony_ci#include "sync/poller.h"
23484543d1Sopenharmony_ci#undef private
24484543d1Sopenharmony_ci#include "util.h"
25484543d1Sopenharmony_ci#include "../common.h"
26484543d1Sopenharmony_ci
27484543d1Sopenharmony_ciusing namespace std;
28484543d1Sopenharmony_ciusing namespace ffrt;
29484543d1Sopenharmony_ciusing namespace testing;
30484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE
31484543d1Sopenharmony_ciusing namespace testing::ext;
32484543d1Sopenharmony_ci#endif
33484543d1Sopenharmony_ci
34484543d1Sopenharmony_ciclass PollerTest : public testing::Test {
35484543d1Sopenharmony_ciprotected:
36484543d1Sopenharmony_ci    static void SetUpTestCase()
37484543d1Sopenharmony_ci    {
38484543d1Sopenharmony_ci    }
39484543d1Sopenharmony_ci
40484543d1Sopenharmony_ci    static void TearDownTestCase()
41484543d1Sopenharmony_ci    {
42484543d1Sopenharmony_ci    }
43484543d1Sopenharmony_ci
44484543d1Sopenharmony_ci    virtual void SetUp()
45484543d1Sopenharmony_ci    {
46484543d1Sopenharmony_ci    }
47484543d1Sopenharmony_ci
48484543d1Sopenharmony_ci    virtual void TearDown()
49484543d1Sopenharmony_ci    {
50484543d1Sopenharmony_ci    }
51484543d1Sopenharmony_ci};
52484543d1Sopenharmony_ci
53484543d1Sopenharmony_cistatic void Testfun(void* data)
54484543d1Sopenharmony_ci{
55484543d1Sopenharmony_ci    int* testData = static_cast<int*>(data);
56484543d1Sopenharmony_ci    *testData += 1;
57484543d1Sopenharmony_ci    printf("%d, timeout callback\n", *testData);
58484543d1Sopenharmony_ci}
59484543d1Sopenharmony_cistatic void (*g_cb)(void*) = Testfun;
60484543d1Sopenharmony_ci
61484543d1Sopenharmony_ci/*
62484543d1Sopenharmony_ci * 测试用例名称:poll_once_batch_timeout
63484543d1Sopenharmony_ci * 测试用例描述:PollOnce批量超时测试
64484543d1Sopenharmony_ci * 预置条件    :无
65484543d1Sopenharmony_ci * 操作步骤    :1、调用注册接口
66484543d1Sopenharmony_ci                2、单次调用PollOnce
67484543d1Sopenharmony_ci * 预期结果    :1、超时任务全部从队列中清除
68484543d1Sopenharmony_ci                2、当实际超时时间很长,但是传入超时时间很短,应该按传入时间执行
69484543d1Sopenharmony_ci */
70484543d1Sopenharmony_ciHWTEST_F(PollerTest, poll_once_batch_timeout, TestSize.Level1)
71484543d1Sopenharmony_ci{
72484543d1Sopenharmony_ci    Poller poller;
73484543d1Sopenharmony_ci    // 1、组装timeMap_
74484543d1Sopenharmony_ci    static int result0 = 0;
75484543d1Sopenharmony_ci    int* xf = &result0;
76484543d1Sopenharmony_ci    void* data = xf;
77484543d1Sopenharmony_ci    uint64_t timeout = 10;
78484543d1Sopenharmony_ci    uint64_t timeout1 = 11;
79484543d1Sopenharmony_ci    uint64_t timeout2 = 12;
80484543d1Sopenharmony_ci    uint64_t sleepTime = 25000;
81484543d1Sopenharmony_ci    poller.RegisterTimer(timeout, data, g_cb, false);
82484543d1Sopenharmony_ci    poller.RegisterTimer(timeout1, data, g_cb, false);
83484543d1Sopenharmony_ci    poller.RegisterTimer(timeout2, data, g_cb, false);
84484543d1Sopenharmony_ci    // 调用PollOnce,预计timerMap_为空,全部清除
85484543d1Sopenharmony_ci    usleep(sleepTime);
86484543d1Sopenharmony_ci    poller.PollOnce(1);
87484543d1Sopenharmony_ci    EXPECT_EQ(true, poller.DetermineEmptyMap());
88484543d1Sopenharmony_ci
89484543d1Sopenharmony_ci    uint64_t timeout3 = 10000;
90484543d1Sopenharmony_ci    uint64_t timeout4 = 100;
91484543d1Sopenharmony_ci    int loopNum = 2;
92484543d1Sopenharmony_ci    poller.RegisterTimer(timeout3, data, g_cb, false);
93484543d1Sopenharmony_ci    TimePoint start = std::chrono::steady_clock::now();
94484543d1Sopenharmony_ci    for (int i = 0; i < loopNum; ++i) {
95484543d1Sopenharmony_ci        poller.PollOnce(timeout4);
96484543d1Sopenharmony_ci    }
97484543d1Sopenharmony_ci    TimePoint end = std::chrono::steady_clock::now();
98484543d1Sopenharmony_ci    int m = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
99484543d1Sopenharmony_ci    // 预计等待时间为100,可能有几毫秒的误差
100484543d1Sopenharmony_ci    EXPECT_EQ(true, m >= timeout4 && m < timeout3);
101484543d1Sopenharmony_ci}
102484543d1Sopenharmony_ci
103484543d1Sopenharmony_ci/*
104484543d1Sopenharmony_ci * 测试用例名称:cache_events_mask_test
105484543d1Sopenharmony_ci * 测试用例描述:本地events缓存
106484543d1Sopenharmony_ci * 预置条件    :无
107484543d1Sopenharmony_ci * 操作步骤    :新增event缓存
108484543d1Sopenharmony_ci * 预期结果    :task对应的events缓存内有没有新增
109484543d1Sopenharmony_ci */
110484543d1Sopenharmony_ciHWTEST_F(PollerTest, cache_events_mask_test, TestSize.Level1)
111484543d1Sopenharmony_ci{
112484543d1Sopenharmony_ci    Poller poller;
113484543d1Sopenharmony_ci    CPUEUTask* currTask;
114484543d1Sopenharmony_ci    EventVec eventVec;
115484543d1Sopenharmony_ci    epoll_event ev;
116484543d1Sopenharmony_ci    eventVec.push_back(ev);
117484543d1Sopenharmony_ci    poller.CacheEventsAndDoMask(currTask, eventVec);
118484543d1Sopenharmony_ci    EXPECT_EQ(1, poller.m_cachedTaskEvents[currTask].size());
119484543d1Sopenharmony_ci}
120484543d1Sopenharmony_ci
121484543d1Sopenharmony_ci/*
122484543d1Sopenharmony_ci * 测试用例名称:fetch_cached_event_unmask
123484543d1Sopenharmony_ci * 测试用例描述:遍历本地events缓存,并提出缓存event
124484543d1Sopenharmony_ci * 预置条件    :无
125484543d1Sopenharmony_ci * 操作步骤    :1、新增event缓存 2、清除缓存
126484543d1Sopenharmony_ci * 预期结果    :task对应的events看有没有去除
127484543d1Sopenharmony_ci */
128484543d1Sopenharmony_ciHWTEST_F(PollerTest, fetch_cached_event_unmask, TestSize.Level1)
129484543d1Sopenharmony_ci{
130484543d1Sopenharmony_ci    Poller poller;
131484543d1Sopenharmony_ci    CPUEUTask* currTask;
132484543d1Sopenharmony_ci    EventVec eventVec;
133484543d1Sopenharmony_ci    epoll_event ev;
134484543d1Sopenharmony_ci    struct epoll_event events[1024];
135484543d1Sopenharmony_ci    eventVec.push_back(ev);
136484543d1Sopenharmony_ci    poller.CacheEventsAndDoMask(currTask, eventVec);
137484543d1Sopenharmony_ci    int fdCnt = poller.FetchCachedEventAndDoUnmask(currTask, events);
138484543d1Sopenharmony_ci    EXPECT_EQ(1, fdCnt);
139484543d1Sopenharmony_ci}
140484543d1Sopenharmony_ci/*
141484543d1Sopenharmony_ci * 测试用例名称:poll_once_batch_timeout
142484543d1Sopenharmony_ci * 测试用例描述:PollOnce批量超时测试
143484543d1Sopenharmony_ci * 预置条件    :无
144484543d1Sopenharmony_ci * 操作步骤    :1、调用注册接口,注册repeat为true的timer
145484543d1Sopenharmony_ci                2、创建两个线程,并发PollerOnce和Unregister
146484543d1Sopenharmony_ci * 预期结果    :1、任务全部从队列中清除
147484543d1Sopenharmony_ci */
148484543d1Sopenharmony_ciHWTEST_F(PollerTest, unregister_timer_001, TestSize.Level1)
149484543d1Sopenharmony_ci{
150484543d1Sopenharmony_ci    Poller poller;
151484543d1Sopenharmony_ci    // 1、组装timeMap_
152484543d1Sopenharmony_ci    static int result0 = 0;
153484543d1Sopenharmony_ci    int* xf = &result0;
154484543d1Sopenharmony_ci    void* data = xf;
155484543d1Sopenharmony_ci    uint64_t timeout = 1;
156484543d1Sopenharmony_ci    uint64_t sleepTime = 2500;
157484543d1Sopenharmony_ci    int maxIter = 100;
158484543d1Sopenharmony_ci    // 2、 创建两个线程,并发PollerOnce和Unregister
159484543d1Sopenharmony_ci    for (int i = 0; i < maxIter; i++) {
160484543d1Sopenharmony_ci        int timerHandle = poller.RegisterTimer(timeout, data, g_cb, true);
161484543d1Sopenharmony_ci        EXPECT_FALSE(poller.timerMap_.empty());
162484543d1Sopenharmony_ci        auto boundPollonce = std::bind(&Poller::PollOnce, &poller, timeout);
163484543d1Sopenharmony_ci        auto boundUnregister = std::bind(&Poller::UnregisterTimer, &poller, timerHandle);
164484543d1Sopenharmony_ci        usleep(sleepTime);
165484543d1Sopenharmony_ci        std::thread thread1(boundPollonce);
166484543d1Sopenharmony_ci        std::thread thread2(boundUnregister);
167484543d1Sopenharmony_ci        thread1.join();
168484543d1Sopenharmony_ci        thread2.join();
169484543d1Sopenharmony_ci        EXPECT_TRUE(poller.timerMap_.empty());
170484543d1Sopenharmony_ci        EXPECT_TRUE(poller.executedHandle_.empty());
171484543d1Sopenharmony_ci        poller.timerMap_.clear();
172484543d1Sopenharmony_ci        poller.executedHandle_.clear();
173484543d1Sopenharmony_ci    }
174484543d1Sopenharmony_ci}