• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
3  * ----------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Render target info.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuApp.hpp"
25 #include "tcuPlatform.hpp"
26 #include "tcuTestContext.hpp"
27 #include "tcuTestExecutor.hpp"
28 #include "tcuCommandLine.hpp"
29 #include "tcuTestLog.hpp"
30 #include "qpInfo.h"
31 #include "qpDebugOut.h"
32 #include "deMath.h"
33 
34 namespace tcu
35 {
36 
watchDogTimeoutFunc(qpWatchDog * watchDog,void * userPtr)37 static void watchDogTimeoutFunc (qpWatchDog* watchDog, void* userPtr)
38 {
39 	DE_UNREF(watchDog);
40 	static_cast<App*>(userPtr)->onWatchdogTimeout();
41 }
42 
crashHandlerFunc(qpCrashHandler * crashHandler,void * userPtr)43 static void crashHandlerFunc (qpCrashHandler* crashHandler, void* userPtr)
44 {
45 	DE_UNREF(crashHandler);
46 	static_cast<App*>(userPtr)->onCrash();
47 }
48 
49 
50 /*--------------------------------------------------------------------*//*!
51  * \brief Construct test application
52  *
53  * If a fatal error occurs during initialization constructor will call
54  * die() with debug information.
55  *
56  * \param platform Reference to platform implementation.
57  *//*--------------------------------------------------------------------*/
App(Platform & platform,Archive & archive,TestLog & log,const CommandLine & cmdLine)58 App::App (Platform& platform, Archive& archive, TestLog& log, const CommandLine& cmdLine)
59 	: m_platform		(platform)
60 	, m_watchDog		(DE_NULL)
61 	, m_crashHandler	(DE_NULL)
62 	, m_crashed			(false)
63 	, m_testCtx			(DE_NULL)
64 	, m_testExecutor	(DE_NULL)
65 {
66 	print("dEQP Core %s (0x%08x) starting..\n", qpGetReleaseName(), qpGetReleaseId());
67 	print("  target implementation = '%s'\n", qpGetTargetName());
68 
69 	if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST))
70 		qpPrintf("WARNING: Failed to set floating-point rounding mode!\n");
71 
72 	try
73 	{
74 		// Initialize watchdog
75 		if (cmdLine.isWatchDogEnabled())
76 			TCU_CHECK(m_watchDog = qpWatchDog_create(watchDogTimeoutFunc, this, 300, 30));
77 
78 		// Initialize crash handler.
79 		if (cmdLine.isCrashHandlingEnabled())
80 			TCU_CHECK(m_crashHandler = qpCrashHandler_create(crashHandlerFunc, this));
81 
82 		// Create test context
83 		m_testCtx = new TestContext(m_platform, archive, log, cmdLine, m_watchDog);
84 
85 		// Create test executor
86 		m_testExecutor = new TestExecutor(*m_testCtx, cmdLine);
87 	}
88 	catch (const std::exception& e)
89 	{
90 		die("Failed to initialize dEQP: %s", e.what());
91 	}
92 }
93 
~App(void)94 App::~App (void)
95 {
96 	delete m_testExecutor;
97 	delete m_testCtx;
98 
99 	if (m_crashHandler)
100 		qpCrashHandler_destroy(m_crashHandler);
101 
102 	if (m_watchDog)
103 		qpWatchDog_destroy(m_watchDog);
104 }
105 
106 
107 /*--------------------------------------------------------------------*//*!
108  * \brief Step forward test execution
109  * \return true if application should call iterate() again and false
110  *         if test execution session is complete.
111  *//*--------------------------------------------------------------------*/
iterate(void)112 bool App::iterate (void)
113 {
114 	// Poll platform events
115 	bool platformOk = m_platform.processEvents();
116 
117 	// Iterate a step.
118 	bool testExecOk = false;
119 	if (platformOk)
120 	{
121 		try
122 		{
123 			testExecOk = m_testExecutor->iterate();
124 		}
125 		catch (const std::exception& e)
126 		{
127 			die("%s", e.what());
128 		}
129 	}
130 
131 	if (!platformOk || !testExecOk)
132 	{
133 		if (!platformOk)
134 			print("\nABORTED!\n");
135 		else
136 			print("\nDONE!\n");
137 
138 		const RunMode runMode = m_testCtx->getCommandLine().getRunMode();
139 		if (runMode == RUNMODE_EXECUTE)
140 		{
141 			const TestRunResult& result = m_testExecutor->getResult();
142 
143 			// Report statistics.
144 			print("\nTest run totals:\n");
145 			print("  Passed:        %d/%d (%.1f%%)\n", result.numPassed,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * result.numPassed		/ result.numExecuted) : 0.0f));
146 			print("  Failed:        %d/%d (%.1f%%)\n", result.numFailed,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * result.numFailed		/ result.numExecuted) : 0.0f));
147 			print("  Not supported: %d/%d (%.1f%%)\n", result.numNotSupported,	result.numExecuted, (result.numExecuted > 0 ? (100.0f * result.numNotSupported	/ result.numExecuted) : 0.0f));
148 			print("  Warnings:      %d/%d (%.1f%%)\n", result.numWarnings,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * result.numWarnings		/ result.numExecuted) : 0.0f));
149 			if (!result.isComplete)
150 				print("Test run was ABORTED!\n");
151 		}
152 	}
153 
154 	return platformOk && testExecOk;
155 }
156 
157 /*--------------------------------------------------------------------*//*!
158  * \brief Get test run result
159  * \return Current test run result.
160  *//*--------------------------------------------------------------------*/
getResult(void) const161 const TestRunResult& App::getResult (void) const
162 {
163 	return m_testExecutor->getResult();
164 }
165 
onWatchdogTimeout(void)166 void App::onWatchdogTimeout (void)
167 {
168 	if (!m_crashLock.tryLock() || m_crashed)
169 		return; // In crash handler already.
170 
171 	m_crashed = true;
172 
173 	m_testCtx->getLog().terminateCase(QP_TEST_RESULT_TIMEOUT);
174 	die("Watchdog timer timeout");
175 }
176 
writeCrashToLog(void * userPtr,const char * infoString)177 static void writeCrashToLog (void* userPtr, const char* infoString)
178 {
179 	TestLog* log = static_cast<TestLog*>(userPtr);
180 	*log << TestLog::Message << infoString << TestLog::EndMessage;
181 }
182 
writeCrashToConsole(void * userPtr,const char * infoString)183 static void writeCrashToConsole (void* userPtr, const char* infoString)
184 {
185 	DE_UNREF(userPtr);
186 	print("%s", infoString);
187 }
188 
onCrash(void)189 void App::onCrash (void)
190 {
191 	if (!m_crashLock.tryLock() || m_crashed)
192 		return; // In crash handler already.
193 
194 	m_crashed = true;
195 
196 	bool isInCase = m_testExecutor ? m_testExecutor->isInTestCase() : false;
197 
198 	if (isInCase)
199 	{
200 		qpCrashHandler_writeCrashInfo(m_crashHandler, writeCrashToLog, &m_testCtx->getLog());
201 		m_testCtx->getLog().terminateCase(QP_TEST_RESULT_CRASH);
202 	}
203 	else
204 		qpCrashHandler_writeCrashInfo(m_crashHandler, writeCrashToConsole, DE_NULL);
205 
206 	die("Test program crashed");
207 }
208 
209 } // tcu
210