1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. 3 * Description:多线程测试框架(GTEST-MULTITHREAD)库,源码移植自CDK 4 * Author: 5 * Create:2023/2/24 6 */ 7 8 #include "gtest/hwext/gtest-multithread.h" 9 #include <iostream> 10 #include <pthread.h> 11 #include <utility> 12 #include <semaphore.h> 13 #include <fcntl.h> 14 #include <semaphore.h> 15 #include <iostream> 16 #include <algorithm> 17 18 namespace testing{ 19 namespace mt { doThreadTestTask(ThreadTaskEntry * task)20 static inline void doThreadTestTask(ThreadTaskEntry *task) 21 { 22 for (const auto &f : task->funcList){ 23 f.m_func(); 24 } 25 } 26 run()27 void MultiThreadTest::run() 28 { 29 int i = 0; 30 for (const auto &_ : randomTasks) { 31 for (const auto &val : _.second) { 32 auto pid = rand() % 100 + i; 33 appendTaskToList(pid, val.m_func, val.m_testsuite, val.m_testcase); 34 } 35 i++; 36 } 37 doTest(); 38 } 39 doTest()40 void MultiThreadTest::doTest() 41 { 42 threadTestEntryList.clear(); 43 for (const auto &task : threadTasks){ 44 threadTestEntryList.push_back(ThreadTaskEntry(task)); 45 } 46 for (auto &test : threadTestEntryList){ 47 test.thread = new std::thread(doThreadTestTask, &test); 48 } 49 auto check = [&](ThreadTaskEntry &t) -> void { 50 if (t.thread){ 51 t.thread->join(); 52 delete t.thread; 53 t.thread = nullptr; 54 } 55 }; 56 std::for_each(threadTestEntryList.begin(), threadTestEntryList.end(), check); 57 } 58 runTask(unsigned thread_num,PF func,std::string testsuite,std::string testcase)59 unsigned MultiThreadTest::runTask(unsigned thread_num, PF func, std::string testsuite, std::string testcase) 60 { 61 MultiThreadFailCaseListener *listener = new MultiThreadFailCaseListener(this); 62 testing::UnitTest::GetInstance()->listeners().Append(listener); 63 if (thread_num == 0){ 64 func(); 65 } 66 unsigned i = 0; 67 for(; i < thread_num; i++){ 68 appendTaskToList(i, func, testsuite, testcase); 69 } 70 i = 0; 71 for (const auto &_ : randomTasks){ 72 for (const auto &val : _.second){ 73 auto pid = rand() % 100 + i; 74 appendTaskToList(pid, val.m_func, val.m_testsuite, val.m_testcase); 75 } 76 i++; 77 } 78 doTest(); 79 testing::UnitTest::GetInstance()->listeners().Release(listener); 80 return 0; 81 } 82 appendTaskToList(unsigned thread_id,PF func,std::string testsuite,std::string testcase)83 void MultiThreadTest::appendTaskToList(unsigned thread_id, PF func, std::string testsuite, std::string testcase) 84 { 85 TestTask task(testsuite, testcase, func); 86 if (thread_id == RANDOM_THREAD_ID){ 87 randomTasks[testsuite].emplace_back(task); 88 return; 89 } 90 while (thread_id >= threadTasks.size()){ 91 threadTasks.push_back(std::vector<TestTask>()); 92 } 93 threadTasks[thread_id].push_back(task); 94 } 95 } 96 }