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 <gtest/gtest.h> 17484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER 18484543d1Sopenharmony_ci#include <mockcpp/mockcpp.hpp> 19484543d1Sopenharmony_ci#endif 20484543d1Sopenharmony_ci#include <thread> 21484543d1Sopenharmony_ci#include <climits> 22484543d1Sopenharmony_ci#include <cstring> 23484543d1Sopenharmony_ci#define private public 24484543d1Sopenharmony_ci#define protected public 25484543d1Sopenharmony_ci#include "eu/worker_manager.h" 26484543d1Sopenharmony_ci#include "eu/scpuworker_manager.h" 27484543d1Sopenharmony_ci#include "sched/task_scheduler.h" 28484543d1Sopenharmony_ci#include "tm/scpu_task.h" 29484543d1Sopenharmony_ci#include "sched/scheduler.h" 30484543d1Sopenharmony_ci#undef private 31484543d1Sopenharmony_ci#undef protected 32484543d1Sopenharmony_ci#include "../common.h" 33484543d1Sopenharmony_ci 34484543d1Sopenharmony_ciusing namespace testing; 35484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE 36484543d1Sopenharmony_ciusing namespace testing::ext; 37484543d1Sopenharmony_ci#endif 38484543d1Sopenharmony_ciusing namespace ffrt; 39484543d1Sopenharmony_ci 40484543d1Sopenharmony_ciclass WorkerManagerTest : public testing::Test { 41484543d1Sopenharmony_ciprotected: 42484543d1Sopenharmony_ci static void SetUpTestCase() 43484543d1Sopenharmony_ci { 44484543d1Sopenharmony_ci } 45484543d1Sopenharmony_ci 46484543d1Sopenharmony_ci static void TearDownTestCase() 47484543d1Sopenharmony_ci { 48484543d1Sopenharmony_ci } 49484543d1Sopenharmony_ci 50484543d1Sopenharmony_ci virtual void SetUp() 51484543d1Sopenharmony_ci { 52484543d1Sopenharmony_ci } 53484543d1Sopenharmony_ci 54484543d1Sopenharmony_ci virtual void TearDown() 55484543d1Sopenharmony_ci { 56484543d1Sopenharmony_ci } 57484543d1Sopenharmony_ci}; 58484543d1Sopenharmony_ci 59484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, JoinRtgTest, TestSize.Level1) 60484543d1Sopenharmony_ci{ 61484543d1Sopenharmony_ci CPUWorkerManager* cm = new SCPUWorkerManager(); 62484543d1Sopenharmony_ci QoS* qos = new QoS(); 63484543d1Sopenharmony_ci cm->IncWorker(*qos); 64484543d1Sopenharmony_ci cm->JoinRtg(*qos); 65484543d1Sopenharmony_ci 66484543d1Sopenharmony_ci delete qos; 67484543d1Sopenharmony_ci delete cm; 68484543d1Sopenharmony_ci} 69484543d1Sopenharmony_ci 70484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, IncWorkerTest, TestSize.Level1) 71484543d1Sopenharmony_ci{ 72484543d1Sopenharmony_ci CPUWorkerManager* cm = new SCPUWorkerManager(); 73484543d1Sopenharmony_ci QoS* qos = new QoS(-1); 74484543d1Sopenharmony_ci cm->IncWorker(*qos); 75484543d1Sopenharmony_ci 76484543d1Sopenharmony_ci delete qos; 77484543d1Sopenharmony_ci delete cm; 78484543d1Sopenharmony_ci} 79484543d1Sopenharmony_ci 80484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, GetWorkerCountTest, TestSize.Level1) 81484543d1Sopenharmony_ci{ 82484543d1Sopenharmony_ci CPUWorkerManager* cm = new SCPUWorkerManager(); 83484543d1Sopenharmony_ci QoS* qos = new QoS(2); 84484543d1Sopenharmony_ci cm->GetWorkerCount(*qos); 85484543d1Sopenharmony_ci 86484543d1Sopenharmony_ci delete qos; 87484543d1Sopenharmony_ci delete cm; 88484543d1Sopenharmony_ci} 89484543d1Sopenharmony_ci 90484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, JoinTGTest, TestSize.Level1) 91484543d1Sopenharmony_ci{ 92484543d1Sopenharmony_ci CPUWorkerManager* cm = new SCPUWorkerManager(); 93484543d1Sopenharmony_ci QoS* qos = new QoS(ffrt::qos_deadline_request); 94484543d1Sopenharmony_ci ThreadGroup* tg = cm->JoinTG(*qos); 95484543d1Sopenharmony_ci EXPECT_NE(tg, nullptr); 96484543d1Sopenharmony_ci 97484543d1Sopenharmony_ci QoS* qos1 = new QoS(ffrt::qos_user_interactive); 98484543d1Sopenharmony_ci ThreadGroup* tg1 = cm->JoinTG(*qos1); 99484543d1Sopenharmony_ci EXPECT_EQ(tg1, nullptr); 100484543d1Sopenharmony_ci} 101484543d1Sopenharmony_ci 102484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, LeaveTGTest, TestSize.Level1) 103484543d1Sopenharmony_ci{ 104484543d1Sopenharmony_ci CPUWorkerManager* cm = new SCPUWorkerManager(); 105484543d1Sopenharmony_ci QoS* qos = new QoS(ffrt::qos_deadline_request); 106484543d1Sopenharmony_ci cm->IncWorker(*qos); 107484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER 108484543d1Sopenharmony_ci MOCKER_CPP(&RTGCtrl::GetThreadGroup).stubs().will(returnValue(1)); 109484543d1Sopenharmony_ci MOCKER_CPP(&RTGCtrl::PutThreadGroup).stubs().will(returnValue(true)); 110484543d1Sopenharmony_ci MOCKER_CPP(&RTGCtrl::JoinThread).stubs().will(returnValue(true)); 111484543d1Sopenharmony_ci MOCKER_CPP(&RTGCtrl::RemoveThread).stubs().will(returnValue(true)); 112484543d1Sopenharmony_ci#endif 113484543d1Sopenharmony_ci cm->JoinTG(*qos); 114484543d1Sopenharmony_ci cm->LeaveTG(*qos); 115484543d1Sopenharmony_ci 116484543d1Sopenharmony_ci delete qos; 117484543d1Sopenharmony_ci delete cm; 118484543d1Sopenharmony_ci#ifndef WITH_NO_MOCKER 119484543d1Sopenharmony_ci GlobalMockObject::verify(); 120484543d1Sopenharmony_ci#endif 121484543d1Sopenharmony_ci} 122484543d1Sopenharmony_ci 123484543d1Sopenharmony_ci#ifdef FFRT_GITEE 124484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, CPUManagerStrategyApiTest, TestSize.Level1) 125484543d1Sopenharmony_ci{ 126484543d1Sopenharmony_ci WorkerManager* manager = new SCPUWorkerManager(); 127484543d1Sopenharmony_ci 128484543d1Sopenharmony_ci CPUMonitor* monitor = CPUManagerStrategy::CreateCPUMonitor(QoS(2), manager); 129484543d1Sopenharmony_ci EXPECT_NE(monitor, nullptr); 130484543d1Sopenharmony_ci delete monitor; 131484543d1Sopenharmony_ci 132484543d1Sopenharmony_ci WorkerThread* worker = CPUManagerStrategy::CreateCPUWorker(QoS(2), manager); 133484543d1Sopenharmony_ci EXPECT_NE(worker, nullptr); 134484543d1Sopenharmony_ci 135484543d1Sopenharmony_ci delete manager; 136484543d1Sopenharmony_ci worker->Join(); 137484543d1Sopenharmony_ci delete worker; 138484543d1Sopenharmony_ci} 139484543d1Sopenharmony_ci#endif 140484543d1Sopenharmony_ci 141484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, CPUWorkerStandardLoopTest, TestSize.Level1) 142484543d1Sopenharmony_ci{ 143484543d1Sopenharmony_ci CPUWorkerManager* manager = new SCPUWorkerManager(); 144484543d1Sopenharmony_ci 145484543d1Sopenharmony_ci CpuWorkerOps ops { 146484543d1Sopenharmony_ci CPUWorker::WorkerLooperStandard, 147484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::PickUpTaskFromGlobalQueue, manager, std::placeholders::_1), 148484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::NotifyTaskPicked, manager, std::placeholders::_1), 149484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::WorkerIdleActionSimplified, manager, std::placeholders::_1), 150484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::WorkerRetired, manager, std::placeholders::_1), 151484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::WorkerPrepare, manager, std::placeholders::_1), 152484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::TryPoll, manager, std::placeholders::_1, std::placeholders::_2), 153484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::StealTaskBatch, manager, std::placeholders::_1), 154484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::PickUpTaskBatch, manager, std::placeholders::_1), 155484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING 156484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::IsExceedRunningThreshold, manager, std::placeholders::_1), 157484543d1Sopenharmony_ci std::bind(&CPUWorkerManager::IsBlockAwareInit, manager), 158484543d1Sopenharmony_ci#endif 159484543d1Sopenharmony_ci }; 160484543d1Sopenharmony_ci WorkerThread* worker = new CPUWorker(QoS(2), std::move(ops), manager); 161484543d1Sopenharmony_ci EXPECT_NE(worker, nullptr); 162484543d1Sopenharmony_ci sleep(1); // wait worker into wait action 163484543d1Sopenharmony_ci manager->NotifyTaskAdded(QoS(2)); // wake worker 164484543d1Sopenharmony_ci 165484543d1Sopenharmony_ci delete manager; 166484543d1Sopenharmony_ci worker->Join(); 167484543d1Sopenharmony_ci delete worker; 168484543d1Sopenharmony_ci} 169484543d1Sopenharmony_ci 170484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, CPUMonitorHandleNotifyConservativeTest, TestSize.Level1) 171484543d1Sopenharmony_ci{ 172484543d1Sopenharmony_ci SCPUWorkerManager* manager = new SCPUWorkerManager(); 173484543d1Sopenharmony_ci 174484543d1Sopenharmony_ci CpuMonitorOps monitorOps { // change monitor's notify handle strategy 175484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::IncWorker, manager, std::placeholders::_1), 176484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::WakeupWorkers, manager, std::placeholders::_1), 177484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::GetTaskCount, manager, std::placeholders::_1), 178484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::GetWorkerCount, manager, std::placeholders::_1), 179484543d1Sopenharmony_ci CPUMonitor::HandleTaskNotifyConservative, 180484543d1Sopenharmony_ci }; 181484543d1Sopenharmony_ci manager->monitor->ops = std::move(monitorOps); 182484543d1Sopenharmony_ci 183484543d1Sopenharmony_ci manager->NotifyTaskAdded(QoS(2)); // task notify event 184484543d1Sopenharmony_ci} 185484543d1Sopenharmony_ci 186484543d1Sopenharmony_ciint GetTaskCountStub(const QoS& qos) 187484543d1Sopenharmony_ci{ 188484543d1Sopenharmony_ci return 1; 189484543d1Sopenharmony_ci} 190484543d1Sopenharmony_ci 191484543d1Sopenharmony_ci/* 192484543d1Sopenharmony_ci * 测试用例名称:CPUMonitorHandleTaskNotifyUltraConservativeTest 193484543d1Sopenharmony_ci * 测试用例描述:ffrt保守调度策略 194484543d1Sopenharmony_ci * 预置条件 :创建SCPUWorkerManager,策略设置为HandleTaskNotifyUltraConservative,GetTaskCount方法打桩为GetTaskCountStub 195484543d1Sopenharmony_ci * 操作步骤 :调用SCPUWorkerManager的Notify方法 196484543d1Sopenharmony_ci * 预期结果 :成功执行HandleTaskNotifyUltraConservative方法 197484543d1Sopenharmony_ci */ 198484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, CPUMonitorHandleTaskNotifyUltraConservativeTest, TestSize.Level1) 199484543d1Sopenharmony_ci{ 200484543d1Sopenharmony_ci SCPUWorkerManager* manager = new SCPUWorkerManager(); 201484543d1Sopenharmony_ci 202484543d1Sopenharmony_ci CpuMonitorOps monitorOps { // change monitor's notify handle strategy 203484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::IncWorker, manager, std::placeholders::_1), 204484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::WakeupWorkers, manager, std::placeholders::_1), 205484543d1Sopenharmony_ci std::bind(&GetTaskCountStub, std::placeholders::_1), 206484543d1Sopenharmony_ci std::bind(&SCPUWorkerManager::GetWorkerCount, manager, std::placeholders::_1), 207484543d1Sopenharmony_ci CPUMonitor::HandleTaskNotifyUltraConservative, 208484543d1Sopenharmony_ci }; 209484543d1Sopenharmony_ci manager->monitor->ops = std::move(monitorOps); 210484543d1Sopenharmony_ci 211484543d1Sopenharmony_ci manager->NotifyTaskAdded(QoS(2)); // task notify event 212484543d1Sopenharmony_ci 213484543d1Sopenharmony_ci manager->monitor->ctrlQueue[2].sleepingWorkerNum = 1; 214484543d1Sopenharmony_ci manager->NotifyTaskAdded(QoS(2)); // task notify event 215484543d1Sopenharmony_ci} 216484543d1Sopenharmony_ci 217484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, PickUpTaskFromGlobalQueue, TestSize.Level1) 218484543d1Sopenharmony_ci{ 219484543d1Sopenharmony_ci CPUWorkerManager* manager = new SCPUWorkerManager(); 220484543d1Sopenharmony_ci CPUManagerStrategy* strategy = new CPUManagerStrategy(); 221484543d1Sopenharmony_ci SCPUEUTask* task = new SCPUEUTask(nullptr, nullptr, 0, QoS(qos(0))); 222484543d1Sopenharmony_ci 223484543d1Sopenharmony_ci auto worker = strategy->CreateCPUWorker(QoS(qos(0)), manager); 224484543d1Sopenharmony_ci auto& sched = FFRTScheduler::Instance()->GetScheduler(worker->GetQos()); 225484543d1Sopenharmony_ci 226484543d1Sopenharmony_ci int ret = sched.WakeupTask(reinterpret_cast<CPUEUTask*>(task)); 227484543d1Sopenharmony_ci EXPECT_EQ(ret, 1); 228484543d1Sopenharmony_ci 229484543d1Sopenharmony_ci auto pickTask = manager->PickUpTaskFromGlobalQueue(worker); 230484543d1Sopenharmony_ci EXPECT_NE(pickTask, nullptr); 231484543d1Sopenharmony_ci 232484543d1Sopenharmony_ci delete worker; 233484543d1Sopenharmony_ci delete task; 234484543d1Sopenharmony_ci delete strategy; 235484543d1Sopenharmony_ci delete manager; 236484543d1Sopenharmony_ci} 237484543d1Sopenharmony_ci 238484543d1Sopenharmony_ciHWTEST_F(WorkerManagerTest, PickUpTaskBatch, TestSize.Level1) 239484543d1Sopenharmony_ci{ 240484543d1Sopenharmony_ci CPUWorkerManager* manager = new SCPUWorkerManager(); 241484543d1Sopenharmony_ci CPUManagerStrategy* strategy = new CPUManagerStrategy(); 242484543d1Sopenharmony_ci SCPUEUTask* task1 = new SCPUEUTask(nullptr, nullptr, 0, QoS(qos(0))); 243484543d1Sopenharmony_ci SCPUEUTask* task2 = new SCPUEUTask(nullptr, nullptr, 0, QoS(qos(0))); 244484543d1Sopenharmony_ci CPUMonitor* monitor = manager->GetCPUMonitor(); 245484543d1Sopenharmony_ci 246484543d1Sopenharmony_ci auto worker1 = strategy->CreateCPUWorker(QoS(qos(0)), manager); 247484543d1Sopenharmony_ci auto worker2 = strategy->CreateCPUWorker(QoS(qos(0)), manager); 248484543d1Sopenharmony_ci 249484543d1Sopenharmony_ci monitor->WakeupDeepSleep(QoS(qos(0)), false); 250484543d1Sopenharmony_ci monitor->WakeupDeepSleep(QoS(qos(0)), false); 251484543d1Sopenharmony_ci 252484543d1Sopenharmony_ci auto& sched1 = FFRTScheduler::Instance()->GetScheduler(worker1->GetQos()); 253484543d1Sopenharmony_ci auto& sched2 = FFRTScheduler::Instance()->GetScheduler(worker2->GetQos()); 254484543d1Sopenharmony_ci 255484543d1Sopenharmony_ci EXPECT_EQ(sched1.WakeupTask(reinterpret_cast<CPUEUTask*>(task1)), 1); 256484543d1Sopenharmony_ci EXPECT_EQ(sched2.WakeupTask(reinterpret_cast<CPUEUTask*>(task2)), 1); 257484543d1Sopenharmony_ci 258484543d1Sopenharmony_ci EXPECT_NE(manager->PickUpTaskBatch(worker1), nullptr); 259484543d1Sopenharmony_ci EXPECT_NE(manager->PickUpTaskBatch(worker2), nullptr); 260484543d1Sopenharmony_ci 261484543d1Sopenharmony_ci delete worker1; 262484543d1Sopenharmony_ci delete worker2; 263484543d1Sopenharmony_ci delete task1; 264484543d1Sopenharmony_ci delete task2; 265484543d1Sopenharmony_ci delete strategy; 266484543d1Sopenharmony_ci delete manager; 267484543d1Sopenharmony_ci}