Exemple #1
0
	threadproc_ret _callconv TestRunner::run(void* pUserData)
	{
		const ThreadInfo* pInfo = static_cast<const ThreadInfo*>(pUserData);
		assert(pInfo);
		assert(pInfo->pRunner);

		TestRunner* pRunner = pInfo->pRunner;
		assert(pRunner->m_testSuiteList);
		assert(pRunner->m_nbTestSuites);

		RTErrorProtector errorProtector(pRunner->m_pTestListener, pInfo->threadIdx);

		TestEvent event;
		stats::CodeTimer suiteTimer;
		stats::CodeTimer caseTimer;
		for (;;)
		{
			bool bStopRequested = pRunner->m_bStopRequested.load(std::memory_order_relaxed);
			if (bStopRequested)
				break;

#ifndef EASYTEST_NO_THREADS
			size_t idx = pRunner->m_nextTestSuiteIdx.fetch_add(1, std::memory_order_relaxed);
#else //EASYTEST_NO_THREADS is defined
			size_t idx = pRunner->m_nextTestSuiteIdx++;
#endif //!EASYTEST_NO_THREADS

			if (idx >= pRunner->m_nbTestSuites)
				break;

			suiteTimer.start();

			const TestSuiteRegistrar* pRegistrar = pRunner->m_testSuiteList[idx];
			bool bTestSuiteSuccess = false;
			TestSuite* pTestSuite = errorProtector.createProtectedTestSuite(pRegistrar);
			if (pTestSuite)
			{
				assert(pRegistrar);
				bTestSuiteSuccess = true;

				const size_t nbTotalCases = pTestSuite->getTestCaseCount();
				size_t nbSuccessCases = 0;
				size_t nbFailedCases = 0;

				if (pRunner->m_pTestListener)
				{
					event.type = TestEventType::TESTSUITE_START;
					event.testSuiteStart.workerThreadIdx = pInfo->threadIdx;
					event.testSuiteStart.testSuiteName = pRegistrar->getTestSuiteName();
					event.testSuiteStart.nbTotalCases = nbTotalCases;
					pRunner->m_pTestListener->onEvent(event);
				}

				const TestCaseRegistrar** caseRegListBegin = pTestSuite->getTestCaseList();
				const TestCaseRegistrar** caseRegListEnd = caseRegListBegin + nbTotalCases;
				for (const TestCaseRegistrar** ppCaseReg = caseRegListBegin; ppCaseReg < caseRegListEnd; ++ppCaseReg)
				{
					assert(*ppCaseReg);

					bStopRequested = pRunner->m_bStopRequested.load(std::memory_order_relaxed);
					if (bStopRequested)
					{
						bTestSuiteSuccess = false;
						break;
					}

					caseTimer.start();

					if (pRunner->m_pTestListener)
					{
						event.type = TestEventType::TESTCASE_START;
						event.testCaseStart.testCaseName = (*ppCaseReg)->getTestName();
						pRunner->m_pTestListener->onEvent(event);
					}

					if (errorProtector.executeProtectedTestCase(*ppCaseReg))
					{
						event.testCaseFinish.bSuccess = true;
						nbSuccessCases++;
					}
					else
					{
						event.testCaseFinish.bSuccess = false;
						nbFailedCases++;
						bTestSuiteSuccess = false;
					}

					caseTimer.stop();

					if (pRunner->m_pTestListener)
					{
						event.type = TestEventType::TESTCASE_FINISH;
						event.testCaseFinish.pTimer = &caseTimer;
						pRunner->m_pTestListener->onEvent(event);
					}
				}

				errorProtector.deleteProtectedTestSuite();

				suiteTimer.stop();

				if (pRunner->m_pTestListener)
				{
					event.type = TestEventType::TESTSUITE_FINISH;
					event.testSuiteFinish.nbTotalCases = nbTotalCases;
					event.testSuiteFinish.nbSuccessCases = nbSuccessCases;
					event.testSuiteFinish.nbFailedCases = nbFailedCases;
					event.testSuiteFinish.pTimer = &suiteTimer;
					pRunner->m_pTestListener->onEvent(event);
				}
			}
			else
				suiteTimer.stop();

			if (!bTestSuiteSuccess)
			{
#ifndef EASYTEST_NO_THREADS
				pRunner->m_nbFailedTestSuites.fetch_add(1, std::memory_order_relaxed);

#else //EASYTEST_NO_THREADS is defined
				pRunner->m_nbFailedTestSuites++;
#endif //!EASYTEST_NO_THREADS
			}

			if (bStopRequested)
				break;
		}

		return 0;
	}