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}