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