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