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 <list> 17484543d1Sopenharmony_ci#include <vector> 18484543d1Sopenharmony_ci#include <queue> 19484543d1Sopenharmony_ci#include <thread> 20484543d1Sopenharmony_ci#include <gtest/gtest.h> 21484543d1Sopenharmony_ci#define private public 22484543d1Sopenharmony_ci#define protect public 23484543d1Sopenharmony_ci#include "ffrt_inner.h" 24484543d1Sopenharmony_ci 25484543d1Sopenharmony_ci#include "core/entity.h" 26484543d1Sopenharmony_ci#include "sched/task_scheduler.h" 27484543d1Sopenharmony_ci#include "sched/task_manager.h" 28484543d1Sopenharmony_ci#include "core/task_attr_private.h" 29484543d1Sopenharmony_ci#include "tm/scpu_task.h" 30484543d1Sopenharmony_ci#include "sched/scheduler.h" 31484543d1Sopenharmony_ci#include "../common.h" 32484543d1Sopenharmony_ci 33484543d1Sopenharmony_ciusing namespace std; 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 SchedulerTest : 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(SchedulerTest, taskstate_test, TestSize.Level1) 60484543d1Sopenharmony_ci{ 61484543d1Sopenharmony_ci std::queue<std::unique_ptr<SCPUEUTask>> tasks; 62484543d1Sopenharmony_ci 63484543d1Sopenharmony_ci std::vector<TaskState::State> produceStatus; 64484543d1Sopenharmony_ci std::vector<TaskState::State> consumeStatus; 65484543d1Sopenharmony_ci 66484543d1Sopenharmony_ci#if (TASKSTAT_LOG_ENABLE == 1) 67484543d1Sopenharmony_ci std::array<uint64_t, static_cast<size_t>(TaskState::MAX)> expectCount; 68484543d1Sopenharmony_ci 69484543d1Sopenharmony_ci // record previous test units count 70484543d1Sopenharmony_ci for (auto state = TaskState::PENDING; state != TaskState::MAX; ++(size_t&)state) { 71484543d1Sopenharmony_ci expectCount[static_cast<size_t>(state)] = TaskManager::Instance().GetCount(state); 72484543d1Sopenharmony_ci } 73484543d1Sopenharmony_ci 74484543d1Sopenharmony_ci // expect non-exited state count equal zero 75484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::PENDING)], 0); 76484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::READY)], 0); 77484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::RUNNING)], 0); 78484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::BLOCKED)], 0); 79484543d1Sopenharmony_ci 80484543d1Sopenharmony_ci auto increCount = [&expectCount](TaskState::State state) { ++expectCount[static_cast<size_t>(state)]; }; 81484543d1Sopenharmony_ci 82484543d1Sopenharmony_ci auto decreCount = [&expectCount](TaskState::State state) { 83484543d1Sopenharmony_ci if (expectCount[static_cast<size_t>(state)] > 0) { 84484543d1Sopenharmony_ci --expectCount[static_cast<size_t>(state)]; 85484543d1Sopenharmony_ci } 86484543d1Sopenharmony_ci }; 87484543d1Sopenharmony_ci#endif 88484543d1Sopenharmony_ci auto setState = [&](CPUEUTask* task) { 89484543d1Sopenharmony_ci consumeStatus.emplace_back(task->state()); 90484543d1Sopenharmony_ci return true; 91484543d1Sopenharmony_ci }; 92484543d1Sopenharmony_ci 93484543d1Sopenharmony_ci auto getNextState = [](TaskState::State state) { 94484543d1Sopenharmony_ci switch (state) { 95484543d1Sopenharmony_ci case TaskState::PENDING: 96484543d1Sopenharmony_ci return TaskState::READY; 97484543d1Sopenharmony_ci case TaskState::READY: 98484543d1Sopenharmony_ci return TaskState::RUNNING; 99484543d1Sopenharmony_ci case TaskState::RUNNING: 100484543d1Sopenharmony_ci return TaskState::BLOCKED; 101484543d1Sopenharmony_ci case TaskState::BLOCKED: 102484543d1Sopenharmony_ci return TaskState::EXITED; 103484543d1Sopenharmony_ci default: 104484543d1Sopenharmony_ci break; 105484543d1Sopenharmony_ci } 106484543d1Sopenharmony_ci return TaskState::MAX; 107484543d1Sopenharmony_ci }; 108484543d1Sopenharmony_ci 109484543d1Sopenharmony_ci TaskState::RegisterOps(TaskState::READY, setState); 110484543d1Sopenharmony_ci TaskState::RegisterOps(TaskState::RUNNING, setState); 111484543d1Sopenharmony_ci TaskState::RegisterOps(TaskState::BLOCKED, setState); 112484543d1Sopenharmony_ci TaskState::RegisterOps(TaskState::EXITED, setState); 113484543d1Sopenharmony_ci 114484543d1Sopenharmony_ci task_attr_private task_attr; 115484543d1Sopenharmony_ci task_attr.name_ = "root"; 116484543d1Sopenharmony_ci auto root = std::make_unique<SCPUEUTask>( 117484543d1Sopenharmony_ci &task_attr, nullptr, 0); 118484543d1Sopenharmony_ci for (int i = 1; i <= 1000; ++i) { 119484543d1Sopenharmony_ci task_attr_private task_attr; 120484543d1Sopenharmony_ci task_attr.name_ = "i"; 121484543d1Sopenharmony_ci tasks.push(std::make_unique<SCPUEUTask>( 122484543d1Sopenharmony_ci &task_attr, root.get(), i)); 123484543d1Sopenharmony_ci } 124484543d1Sopenharmony_ci 125484543d1Sopenharmony_ci while (!tasks.empty()) { 126484543d1Sopenharmony_ci auto task = std::move(tasks.front()); 127484543d1Sopenharmony_ci tasks.pop(); 128484543d1Sopenharmony_ci 129484543d1Sopenharmony_ci auto state = getNextState(task->state()); 130484543d1Sopenharmony_ci if (state == TaskState::MAX) { 131484543d1Sopenharmony_ci continue; 132484543d1Sopenharmony_ci } 133484543d1Sopenharmony_ci 134484543d1Sopenharmony_ci produceStatus.emplace_back(state); 135484543d1Sopenharmony_ci 136484543d1Sopenharmony_ci task->UpdateState(state); 137484543d1Sopenharmony_ci 138484543d1Sopenharmony_ci#if (TASKSTAT_LOG_ENABLE == 1) 139484543d1Sopenharmony_ci auto preState = task->state.PreState(); 140484543d1Sopenharmony_ci auto curState = task->state.CurState(); 141484543d1Sopenharmony_ci 142484543d1Sopenharmony_ci decreCount(preState); 143484543d1Sopenharmony_ci increCount(curState); 144484543d1Sopenharmony_ci 145484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(preState)], TaskManager::Instance().GetCount(preState)); 146484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(curState)], TaskManager::Instance().GetCount(curState)); 147484543d1Sopenharmony_ci#endif 148484543d1Sopenharmony_ci 149484543d1Sopenharmony_ci tasks.push(std::move(task)); 150484543d1Sopenharmony_ci } 151484543d1Sopenharmony_ci 152484543d1Sopenharmony_ci#if (TRACE_TASKSTAT_LOG_ENABLE == 1) 153484543d1Sopenharmony_ci EXPECT_EQ( 154484543d1Sopenharmony_ci expectCount[static_cast<size_t>(TaskState::PENDING)], TaskManager::Instance().GetCount(TaskState::PENDING)); 155484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::READY)], TaskManager::Instance().GetCount(TaskState::READY)); 156484543d1Sopenharmony_ci EXPECT_EQ( 157484543d1Sopenharmony_ci expectCount[static_cast<size_t>(TaskState::RUNNING)], TaskManager::Instance().GetCount(TaskState::RUNNING)); 158484543d1Sopenharmony_ci EXPECT_EQ( 159484543d1Sopenharmony_ci expectCount[static_cast<size_t>(TaskState::BLOCKED)], TaskManager::Instance().GetCount(TaskState::BLOCKED)); 160484543d1Sopenharmony_ci EXPECT_EQ(expectCount[static_cast<size_t>(TaskState::EXITED)], TaskManager::Instance().GetCount(TaskState::EXITED)); 161484543d1Sopenharmony_ci#endif 162484543d1Sopenharmony_ci 163484543d1Sopenharmony_ci EXPECT_EQ(produceStatus.size(), consumeStatus.size()); 164484543d1Sopenharmony_ci 165484543d1Sopenharmony_ci int size = produceStatus.size(); 166484543d1Sopenharmony_ci for (int i = 0; i < size; ++i) { 167484543d1Sopenharmony_ci EXPECT_EQ(produceStatus[i], consumeStatus[i]); 168484543d1Sopenharmony_ci } 169484543d1Sopenharmony_ci} 170484543d1Sopenharmony_ci 171484543d1Sopenharmony_ciHWTEST_F(SchedulerTest, taskstateCount_test, TestSize.Level1) 172484543d1Sopenharmony_ci{ 173484543d1Sopenharmony_ci SCPUEUTask* task1 = new SCPUEUTask(nullptr, nullptr, 0, QoS(static_cast<int>(qos_user_interactive))); 174484543d1Sopenharmony_ci SCPUEUTask *task2 = new SCPUEUTask(nullptr, task1, 0, QoS()); 175484543d1Sopenharmony_ci TaskManager::Instance().TaskStateCount(task2); 176484543d1Sopenharmony_ci} 177484543d1Sopenharmony_ci 178484543d1Sopenharmony_ciHWTEST_F(SchedulerTest, ffrt_task_runqueue_test, TestSize.Level1) 179484543d1Sopenharmony_ci{ 180484543d1Sopenharmony_ci ffrt::FIFOQueue *fifoqueue = new ffrt::FIFOQueue(); 181484543d1Sopenharmony_ci int aimnum = 10; 182484543d1Sopenharmony_ci for (int i = 0; i < aimnum ; i++) { 183484543d1Sopenharmony_ci SCPUEUTask* task = new SCPUEUTask(nullptr, nullptr, 0, QoS(static_cast<int>(qos_user_interactive))); 184484543d1Sopenharmony_ci fifoqueue->EnQueue(task); 185484543d1Sopenharmony_ci } 186484543d1Sopenharmony_ci EXPECT_EQ(fifoqueue->Size(), aimnum); 187484543d1Sopenharmony_ci EXPECT_EQ(fifoqueue->Empty(), false); 188484543d1Sopenharmony_ci} 189484543d1Sopenharmony_ci 190484543d1Sopenharmony_ciHWTEST_F(SchedulerTest, ffrt_scheduler_test, TestSize.Level1) 191484543d1Sopenharmony_ci{ 192484543d1Sopenharmony_ci ffrt::SFFRTScheduler *sffrtscheduler = new ffrt::SFFRTScheduler(); 193484543d1Sopenharmony_ci LinkedList* node = new LinkedList(); 194484543d1Sopenharmony_ci QoS qos; 195484543d1Sopenharmony_ci EXPECT_EQ(sffrtscheduler->InsertNode(node, qos), true); 196484543d1Sopenharmony_ci EXPECT_EQ(sffrtscheduler->RemoveNode(node, qos), true); 197484543d1Sopenharmony_ci 198484543d1Sopenharmony_ci delete node; 199484543d1Sopenharmony_ci} 200