1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. 3 * Description:多线程测试框架(GTEST-MULTITHREAD)库接口声明 4 * Author: 5 * Create:2023/2/24 6 */ 7 8 #ifndef __MULTI_THREAD_TEST_H__ 9 #define __MULTI_THREAD_TEST_H__ 10 11 #include <vector> 12 #include <string> 13 #include <map> 14 #include <thread> 15 #include "gtest/gtest.h" 16 17 using ::testing::TestPartResult; 18 19 namespace testing{ 20 namespace mt { 21 using PF = void(*)(); 22 using uint = unsigned int; 23 const uint RANDOM_THREAD_ID = 0x3f3f3f3f; //线程ID常量 24 static uint g_thread_count = 10 ; //全局变量,默认线程数是10 setThreadNum(uint num)25 inline void setThreadNum(uint num) 26 { 27 g_thread_count = num; 28 } 29 class TestTask { 30 public: 31 TestTask() = default; TestTask(std::string ts,std::string tc,PF func)32 TestTask(std::string ts, std::string tc, PF func) : m_testsuite(ts), m_testcase(tc), m_func(func){} 33 std::string m_testsuite; 34 std::string m_testcase; 35 PF m_func; 36 }; 37 class ThreadTaskEntry { 38 public: ThreadTaskEntry(std::vector<TestTask> v_task)39 ThreadTaskEntry(std::vector<TestTask> v_task) : funcList(v_task) {} 40 std::thread *thread; 41 std::vector<TestTask> funcList; 42 }; 43 class MultiThreadTest { 44 private: 45 std::vector<std::vector<TestTask>> threadTasks; 46 std::vector<ThreadTaskEntry> threadTestEntryList; 47 std::map<std::string, std::vector<TestTask>> randomTasks; 48 49 public: 50 void doTest(); 51 void run(); MultiThreadTest()52 MultiThreadTest() {} 53 unsigned m_threadNum; MultiThreadTest(unsigned int t_cnt)54 MultiThreadTest(unsigned int t_cnt) : m_threadNum(t_cnt) {} 55 uint runTask(unsigned thread_num, PF func, std::string testsuite, std::string testcase); 56 void appendTaskToList(unsigned thread_id, PF func, std::string testsuite, std::string testcase); 57 }; 58 59 static MultiThreadTest testInstance; getMTestSingleton()60 static MultiThreadTest *getMTestSingleton() 61 { 62 return &testInstance; 63 } 64 getMTest()65 inline void getMTest() 66 { 67 auto ret = getMTestSingleton(); 68 if (ret == nullptr) { 69 return; 70 } 71 } 72 73 class MultiThreadFailCaseListener : public EmptyTestEventListener { 74 private: 75 MultiThreadTest *testInstance; 76 public: MultiThreadFailCaseListener(MultiThreadTest * ins)77 MultiThreadFailCaseListener(MultiThreadTest *ins) 78 { 79 this->testInstance = ins; 80 } 81 }; 82 83 inline void addPostTest(unsigned thread_id, PF func, std::string testsuite = "NA", std::string testcase = "NA") 84 { 85 for (unsigned int i = 0; i < g_thread_count; i++) { 86 testInstance.appendTaskToList(thread_id, func, testsuite, testcase); 87 } 88 } 89 90 #define MTEST_ADD_TASK(thread_id, func) addPostTest(thread_id, func) 91 92 #define MTEST_POST_RUN() \ 93 do { \ 94 getMTestSingleton()->run(); \ 95 } while (0) 96 97 #define SET_THREAD_NUM(n) setThreadNum(n) 98 #define MTEST_FUNC_NAME(x, y) TC_##x_##y 99 #define GTEST_RUN_TASK(hook) \ 100 do { \ 101 MultiThreadTest _test(g_thread_count); \ 102 _test.runTask(_test.m_threadNum, hook, this->test_info_->test_case_name(), this->test_info_->name()); \ 103 } while (0) 104 105 #define MTEST_TYPE(x, y, z, n) \ 106 void MTEST_FUNC_NAME(x, y)(); \ 107 z(x, y) \ 108 { \ 109 SET_THREAD_NUM(n); \ 110 GTEST_RUN_TASK(MTEST_FUNC_NAME(x, y)); \ 111 } \ 112 void MTEST_FUNC_NAME(x, y)() 113 #define HWMTEST(x, y, w, n) MTEST_TYPE(x, y, TEST, n) 114 #define HWMTEST_F(x, y, w, n) MTEST_TYPE(x, y, TEST_F, n) 115 } 116 } 117 #endif /* __MULTI_THREAD_TEST_H__ */