• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }