xref: /aosp_15_r20/external/deqp/framework/common/tcuTestSessionExecutor.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Tester Core
3*35238bceSAndroid Build Coastguard Worker  * ----------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Test executor.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "tcuTestSessionExecutor.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "qpTestLog.h"
26*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker namespace tcu
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker using std::vector;
35*35238bceSAndroid Build Coastguard Worker 
nodeTypeToTestCaseType(TestNodeType nodeType)36*35238bceSAndroid Build Coastguard Worker static qpTestCaseType nodeTypeToTestCaseType(TestNodeType nodeType)
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker     switch (nodeType)
39*35238bceSAndroid Build Coastguard Worker     {
40*35238bceSAndroid Build Coastguard Worker     case NODETYPE_SELF_VALIDATE:
41*35238bceSAndroid Build Coastguard Worker         return QP_TEST_CASE_TYPE_SELF_VALIDATE;
42*35238bceSAndroid Build Coastguard Worker     case NODETYPE_PERFORMANCE:
43*35238bceSAndroid Build Coastguard Worker         return QP_TEST_CASE_TYPE_PERFORMANCE;
44*35238bceSAndroid Build Coastguard Worker     case NODETYPE_CAPABILITY:
45*35238bceSAndroid Build Coastguard Worker         return QP_TEST_CASE_TYPE_CAPABILITY;
46*35238bceSAndroid Build Coastguard Worker     case NODETYPE_ACCURACY:
47*35238bceSAndroid Build Coastguard Worker         return QP_TEST_CASE_TYPE_ACCURACY;
48*35238bceSAndroid Build Coastguard Worker     default:
49*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
50*35238bceSAndroid Build Coastguard Worker         return QP_TEST_CASE_TYPE_LAST;
51*35238bceSAndroid Build Coastguard Worker     }
52*35238bceSAndroid Build Coastguard Worker }
53*35238bceSAndroid Build Coastguard Worker 
TestSessionExecutor(TestPackageRoot & root,TestContext & testCtx)54*35238bceSAndroid Build Coastguard Worker TestSessionExecutor::TestSessionExecutor(TestPackageRoot &root, TestContext &testCtx)
55*35238bceSAndroid Build Coastguard Worker     : m_testCtx(testCtx)
56*35238bceSAndroid Build Coastguard Worker     , m_inflater(testCtx)
57*35238bceSAndroid Build Coastguard Worker     , m_caseListFilter(testCtx.getCommandLine().createCaseListFilter(testCtx.getArchive()))
58*35238bceSAndroid Build Coastguard Worker     , m_iterator(root, m_inflater, *m_caseListFilter)
59*35238bceSAndroid Build Coastguard Worker     , m_state(STATE_TRAVERSE_HIERARCHY)
60*35238bceSAndroid Build Coastguard Worker     , m_abortSession(false)
61*35238bceSAndroid Build Coastguard Worker     , m_isInTestCase(false)
62*35238bceSAndroid Build Coastguard Worker     , m_testStartTime(0)
63*35238bceSAndroid Build Coastguard Worker     , m_packageStartTime(0)
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker }
66*35238bceSAndroid Build Coastguard Worker 
~TestSessionExecutor(void)67*35238bceSAndroid Build Coastguard Worker TestSessionExecutor::~TestSessionExecutor(void)
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker }
70*35238bceSAndroid Build Coastguard Worker 
iterate(void)71*35238bceSAndroid Build Coastguard Worker bool TestSessionExecutor::iterate(void)
72*35238bceSAndroid Build Coastguard Worker {
73*35238bceSAndroid Build Coastguard Worker     while (!m_abortSession)
74*35238bceSAndroid Build Coastguard Worker     {
75*35238bceSAndroid Build Coastguard Worker         switch (m_state)
76*35238bceSAndroid Build Coastguard Worker         {
77*35238bceSAndroid Build Coastguard Worker         case STATE_TRAVERSE_HIERARCHY:
78*35238bceSAndroid Build Coastguard Worker         {
79*35238bceSAndroid Build Coastguard Worker             const TestHierarchyIterator::State hierIterState = m_iterator.getState();
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker             if (hierIterState == TestHierarchyIterator::STATE_ENTER_NODE ||
82*35238bceSAndroid Build Coastguard Worker                 hierIterState == TestHierarchyIterator::STATE_LEAVE_NODE)
83*35238bceSAndroid Build Coastguard Worker             {
84*35238bceSAndroid Build Coastguard Worker                 TestNode *const curNode     = m_iterator.getNode();
85*35238bceSAndroid Build Coastguard Worker                 const TestNodeType nodeType = curNode->getNodeType();
86*35238bceSAndroid Build Coastguard Worker                 const bool isEnter          = hierIterState == TestHierarchyIterator::STATE_ENTER_NODE;
87*35238bceSAndroid Build Coastguard Worker 
88*35238bceSAndroid Build Coastguard Worker                 switch (nodeType)
89*35238bceSAndroid Build Coastguard Worker                 {
90*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_PACKAGE:
91*35238bceSAndroid Build Coastguard Worker                 {
92*35238bceSAndroid Build Coastguard Worker                     TestPackage *const testPackage = static_cast<TestPackage *>(curNode);
93*35238bceSAndroid Build Coastguard Worker                     isEnter ? enterTestPackage(testPackage) : leaveTestPackage(testPackage);
94*35238bceSAndroid Build Coastguard Worker                     break;
95*35238bceSAndroid Build Coastguard Worker                 }
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_GROUP:
98*35238bceSAndroid Build Coastguard Worker                 {
99*35238bceSAndroid Build Coastguard Worker                     isEnter ? enterTestGroup(m_iterator.getNodePath()) : leaveTestGroup(m_iterator.getNodePath());
100*35238bceSAndroid Build Coastguard Worker                     break; // nada
101*35238bceSAndroid Build Coastguard Worker                 }
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_SELF_VALIDATE:
104*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_PERFORMANCE:
105*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_CAPABILITY:
106*35238bceSAndroid Build Coastguard Worker                 case NODETYPE_ACCURACY:
107*35238bceSAndroid Build Coastguard Worker                 {
108*35238bceSAndroid Build Coastguard Worker                     TestCase *const testCase = static_cast<TestCase *>(curNode);
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker                     if (isEnter)
111*35238bceSAndroid Build Coastguard Worker                     {
112*35238bceSAndroid Build Coastguard Worker                         if (enterTestCase(testCase, m_iterator.getNodePath()))
113*35238bceSAndroid Build Coastguard Worker                             m_state = STATE_EXECUTE_TEST_CASE;
114*35238bceSAndroid Build Coastguard Worker                         // else remain in TRAVERSING_HIERARCHY => node will be exited from in the next iteration
115*35238bceSAndroid Build Coastguard Worker                     }
116*35238bceSAndroid Build Coastguard Worker                     else
117*35238bceSAndroid Build Coastguard Worker                         leaveTestCase(testCase);
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker                     break;
120*35238bceSAndroid Build Coastguard Worker                 }
121*35238bceSAndroid Build Coastguard Worker 
122*35238bceSAndroid Build Coastguard Worker                 default:
123*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
124*35238bceSAndroid Build Coastguard Worker                     break;
125*35238bceSAndroid Build Coastguard Worker                 }
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker                 m_iterator.next();
128*35238bceSAndroid Build Coastguard Worker                 break;
129*35238bceSAndroid Build Coastguard Worker             }
130*35238bceSAndroid Build Coastguard Worker             else
131*35238bceSAndroid Build Coastguard Worker             {
132*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(hierIterState == TestHierarchyIterator::STATE_FINISHED);
133*35238bceSAndroid Build Coastguard Worker                 m_status.isComplete = true;
134*35238bceSAndroid Build Coastguard Worker                 return false;
135*35238bceSAndroid Build Coastguard Worker             }
136*35238bceSAndroid Build Coastguard Worker         }
137*35238bceSAndroid Build Coastguard Worker 
138*35238bceSAndroid Build Coastguard Worker         case STATE_EXECUTE_TEST_CASE:
139*35238bceSAndroid Build Coastguard Worker         {
140*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(m_iterator.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
141*35238bceSAndroid Build Coastguard Worker                       isTestNodeTypeExecutable(m_iterator.getNode()->getNodeType()));
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker             TestCase *const testCase                 = static_cast<TestCase *>(m_iterator.getNode());
144*35238bceSAndroid Build Coastguard Worker             const TestCase::IterateResult iterResult = iterateTestCase(testCase);
145*35238bceSAndroid Build Coastguard Worker 
146*35238bceSAndroid Build Coastguard Worker             if (iterResult == TestCase::STOP)
147*35238bceSAndroid Build Coastguard Worker                 m_state = STATE_TRAVERSE_HIERARCHY;
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker             return true;
150*35238bceSAndroid Build Coastguard Worker         }
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker         default:
153*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
154*35238bceSAndroid Build Coastguard Worker             break;
155*35238bceSAndroid Build Coastguard Worker         }
156*35238bceSAndroid Build Coastguard Worker     }
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker     return false;
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker 
enterTestPackage(TestPackage * testPackage)161*35238bceSAndroid Build Coastguard Worker void TestSessionExecutor::enterTestPackage(TestPackage *testPackage)
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker     // Create test case wrapper
164*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_caseExecutor);
165*35238bceSAndroid Build Coastguard Worker     m_caseExecutor = de::MovePtr<TestCaseExecutor>(testPackage->createExecutor());
166*35238bceSAndroid Build Coastguard Worker     testPackage->setCaseListFilter(m_caseListFilter.get());
167*35238bceSAndroid Build Coastguard Worker     m_packageStartTime = deGetMicroseconds();
168*35238bceSAndroid Build Coastguard Worker }
169*35238bceSAndroid Build Coastguard Worker 
leaveTestPackage(TestPackage * testPackage)170*35238bceSAndroid Build Coastguard Worker void TestSessionExecutor::leaveTestPackage(TestPackage *testPackage)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker     DE_UNREF(testPackage);
173*35238bceSAndroid Build Coastguard Worker     m_caseExecutor->deinitTestPackage(m_testCtx);
174*35238bceSAndroid Build Coastguard Worker     // If m_caseExecutor uses local status then it may perform some tests in deinitTestPackage(). We have to update TestSessionExecutor::m_status
175*35238bceSAndroid Build Coastguard Worker     if (m_caseExecutor->usesLocalStatus())
176*35238bceSAndroid Build Coastguard Worker         m_caseExecutor->updateGlobalStatus(m_status);
177*35238bceSAndroid Build Coastguard Worker 
178*35238bceSAndroid Build Coastguard Worker     const int64_t duration = deGetMicroseconds() - m_packageStartTime;
179*35238bceSAndroid Build Coastguard Worker     m_packageStartTime     = 0;
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker     if (!std::string(m_testCtx.getCommandLine().getServerAddress()).empty())
182*35238bceSAndroid Build Coastguard Worker         m_caseExecutor->reportDurations(m_testCtx, std::string(testPackage->getName()), duration, m_groupsDurationTime);
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker     m_caseExecutor.clear();
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker     if (!std::string(m_testCtx.getCommandLine().getServerAddress()).empty())
187*35238bceSAndroid Build Coastguard Worker     {
188*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog().startTestsCasesTime();
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Integer(testPackage->getName(), "Total tests case duration in microseconds",
191*35238bceSAndroid Build Coastguard Worker                                                "us", QP_KEY_TAG_TIME, duration);
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker         for (std::map<std::string, uint64_t>::iterator it = m_groupsDurationTime.begin();
194*35238bceSAndroid Build Coastguard Worker              it != m_groupsDurationTime.end(); ++it)
195*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Integer(it->first, "The test group case duration in microseconds", "us",
196*35238bceSAndroid Build Coastguard Worker                                                    QP_KEY_TAG_TIME, it->second);
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog().endTestsCasesTime();
199*35238bceSAndroid Build Coastguard Worker     }
200*35238bceSAndroid Build Coastguard Worker }
201*35238bceSAndroid Build Coastguard Worker 
enterTestGroup(const std::string & casePath)202*35238bceSAndroid Build Coastguard Worker void TestSessionExecutor::enterTestGroup(const std::string &casePath)
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker     m_groupsDurationTime[casePath] = deGetMicroseconds();
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker 
leaveTestGroup(const std::string & casePath)207*35238bceSAndroid Build Coastguard Worker void TestSessionExecutor::leaveTestGroup(const std::string &casePath)
208*35238bceSAndroid Build Coastguard Worker {
209*35238bceSAndroid Build Coastguard Worker     m_groupsDurationTime[casePath] = deGetMicroseconds() - m_groupsDurationTime[casePath];
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker 
enterTestCase(TestCase * testCase,const std::string & casePath)212*35238bceSAndroid Build Coastguard Worker bool TestSessionExecutor::enterTestCase(TestCase *testCase, const std::string &casePath)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker     TestLog &log                  = m_testCtx.getLog();
215*35238bceSAndroid Build Coastguard Worker     const qpTestCaseType caseType = nodeTypeToTestCaseType(testCase->getNodeType());
216*35238bceSAndroid Build Coastguard Worker     bool initOk                   = false;
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker     print("\nTest case '%s'..\n", casePath.c_str());
219*35238bceSAndroid Build Coastguard Worker 
220*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
221*35238bceSAndroid Build Coastguard Worker     fflush(stdout);
222*35238bceSAndroid Build Coastguard Worker #endif
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_LAST, "");
225*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTerminateAfter(false);
226*35238bceSAndroid Build Coastguard Worker     log.startCase(casePath.c_str(), caseType);
227*35238bceSAndroid Build Coastguard Worker 
228*35238bceSAndroid Build Coastguard Worker     m_isInTestCase  = true;
229*35238bceSAndroid Build Coastguard Worker     m_testStartTime = deGetMicroseconds();
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker     try
232*35238bceSAndroid Build Coastguard Worker     {
233*35238bceSAndroid Build Coastguard Worker         m_caseExecutor->init(testCase, casePath);
234*35238bceSAndroid Build Coastguard Worker         initOk = true;
235*35238bceSAndroid Build Coastguard Worker     }
236*35238bceSAndroid Build Coastguard Worker     catch (const std::bad_alloc &)
237*35238bceSAndroid Build Coastguard Worker     {
238*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!initOk);
239*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Failed to allocate memory in test case init");
240*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(true);
241*35238bceSAndroid Build Coastguard Worker     }
242*35238bceSAndroid Build Coastguard Worker     catch (const tcu::TestException &e)
243*35238bceSAndroid Build Coastguard Worker     {
244*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!initOk);
245*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(e.getTestResult() != QP_TEST_RESULT_LAST);
246*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(e.getTestResult(), e.getMessage());
247*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(e.isFatal());
248*35238bceSAndroid Build Coastguard Worker         log << e;
249*35238bceSAndroid Build Coastguard Worker     }
250*35238bceSAndroid Build Coastguard Worker     catch (const tcu::Exception &e)
251*35238bceSAndroid Build Coastguard Worker     {
252*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!initOk);
253*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage());
254*35238bceSAndroid Build Coastguard Worker         log << e;
255*35238bceSAndroid Build Coastguard Worker     }
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(initOk || m_testCtx.getTestResult() != QP_TEST_RESULT_LAST);
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker     return initOk;
260*35238bceSAndroid Build Coastguard Worker }
261*35238bceSAndroid Build Coastguard Worker 
leaveTestCase(TestCase * testCase)262*35238bceSAndroid Build Coastguard Worker void TestSessionExecutor::leaveTestCase(TestCase *testCase)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
265*35238bceSAndroid Build Coastguard Worker 
266*35238bceSAndroid Build Coastguard Worker     // De-init case.
267*35238bceSAndroid Build Coastguard Worker     try
268*35238bceSAndroid Build Coastguard Worker     {
269*35238bceSAndroid Build Coastguard Worker         m_caseExecutor->deinit(testCase);
270*35238bceSAndroid Build Coastguard Worker     }
271*35238bceSAndroid Build Coastguard Worker     catch (const tcu::Exception &e)
272*35238bceSAndroid Build Coastguard Worker     {
273*35238bceSAndroid Build Coastguard Worker         const bool suppressLogging = m_testCtx.getLog().isSupressLogging();
274*35238bceSAndroid Build Coastguard Worker 
275*35238bceSAndroid Build Coastguard Worker         if (suppressLogging)
276*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog().supressLogging(false);
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker         log << e << TestLog::Message << "Error in test case deinit, test program will terminate."
279*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
280*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(true);
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog().supressLogging(suppressLogging);
283*35238bceSAndroid Build Coastguard Worker     }
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker     {
286*35238bceSAndroid Build Coastguard Worker         const int64_t duration = deGetMicroseconds() - m_testStartTime;
287*35238bceSAndroid Build Coastguard Worker         m_testStartTime        = 0;
288*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Integer("TestDuration", "Test case duration in microseconds", "us",
289*35238bceSAndroid Build Coastguard Worker                                                QP_KEY_TAG_TIME, duration);
290*35238bceSAndroid Build Coastguard Worker     }
291*35238bceSAndroid Build Coastguard Worker 
292*35238bceSAndroid Build Coastguard Worker     {
293*35238bceSAndroid Build Coastguard Worker         const qpTestResult testResult    = m_testCtx.getTestResult();
294*35238bceSAndroid Build Coastguard Worker         const char *const testResultDesc = m_testCtx.getTestResultDesc();
295*35238bceSAndroid Build Coastguard Worker         const bool terminateAfter        = m_testCtx.getTerminateAfter();
296*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(testResult != QP_TEST_RESULT_LAST);
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker         m_isInTestCase = false;
299*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog().endCase(testResult, testResultDesc);
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker         // Update statistics.
302*35238bceSAndroid Build Coastguard Worker         print("  %s (%s)\n", qpGetTestResultName(testResult), testResultDesc);
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker #if (DE_OS == DE_OS_WIN32)
305*35238bceSAndroid Build Coastguard Worker         fflush(stdout);
306*35238bceSAndroid Build Coastguard Worker #endif
307*35238bceSAndroid Build Coastguard Worker         if (!m_caseExecutor->usesLocalStatus())
308*35238bceSAndroid Build Coastguard Worker         {
309*35238bceSAndroid Build Coastguard Worker             m_status.numExecuted += 1;
310*35238bceSAndroid Build Coastguard Worker             switch (testResult)
311*35238bceSAndroid Build Coastguard Worker             {
312*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_PASS:
313*35238bceSAndroid Build Coastguard Worker                 m_status.numPassed += 1;
314*35238bceSAndroid Build Coastguard Worker                 break;
315*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_NOT_SUPPORTED:
316*35238bceSAndroid Build Coastguard Worker                 m_status.numNotSupported += 1;
317*35238bceSAndroid Build Coastguard Worker                 break;
318*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_QUALITY_WARNING:
319*35238bceSAndroid Build Coastguard Worker                 m_status.numWarnings += 1;
320*35238bceSAndroid Build Coastguard Worker                 break;
321*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_COMPATIBILITY_WARNING:
322*35238bceSAndroid Build Coastguard Worker                 m_status.numWarnings += 1;
323*35238bceSAndroid Build Coastguard Worker                 break;
324*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_WAIVER:
325*35238bceSAndroid Build Coastguard Worker                 m_status.numWaived += 1;
326*35238bceSAndroid Build Coastguard Worker                 break;
327*35238bceSAndroid Build Coastguard Worker             case QP_TEST_RESULT_DEVICE_LOST:
328*35238bceSAndroid Build Coastguard Worker                 m_status.numDeviceLost += 1;
329*35238bceSAndroid Build Coastguard Worker                 m_status.numFailed += 1;
330*35238bceSAndroid Build Coastguard Worker                 break;
331*35238bceSAndroid Build Coastguard Worker             default:
332*35238bceSAndroid Build Coastguard Worker                 m_status.numFailed += 1;
333*35238bceSAndroid Build Coastguard Worker                 break;
334*35238bceSAndroid Build Coastguard Worker             }
335*35238bceSAndroid Build Coastguard Worker         }
336*35238bceSAndroid Build Coastguard Worker         else
337*35238bceSAndroid Build Coastguard Worker         {
338*35238bceSAndroid Build Coastguard Worker             m_caseExecutor->updateGlobalStatus(m_status);
339*35238bceSAndroid Build Coastguard Worker         }
340*35238bceSAndroid Build Coastguard Worker 
341*35238bceSAndroid Build Coastguard Worker         // terminateAfter, Resource error or any error in deinit means that execution should end
342*35238bceSAndroid Build Coastguard Worker         if (terminateAfter || testResult == QP_TEST_RESULT_RESOURCE_ERROR ||
343*35238bceSAndroid Build Coastguard Worker             (m_status.numFailed > 0 && m_testCtx.getCommandLine().isTerminateOnFailEnabled()) ||
344*35238bceSAndroid Build Coastguard Worker             (m_status.numDeviceLost > 0 && m_testCtx.getCommandLine().isTerminateOnDeviceLostEnabled()))
345*35238bceSAndroid Build Coastguard Worker 
346*35238bceSAndroid Build Coastguard Worker             m_abortSession = true;
347*35238bceSAndroid Build Coastguard Worker     }
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker     if (m_testCtx.getWatchDog())
350*35238bceSAndroid Build Coastguard Worker         qpWatchDog_reset(m_testCtx.getWatchDog());
351*35238bceSAndroid Build Coastguard Worker }
352*35238bceSAndroid Build Coastguard Worker 
iterateTestCase(TestCase * testCase)353*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult TestSessionExecutor::iterateTestCase(TestCase *testCase)
354*35238bceSAndroid Build Coastguard Worker {
355*35238bceSAndroid Build Coastguard Worker     TestLog &log                          = m_testCtx.getLog();
356*35238bceSAndroid Build Coastguard Worker     TestCase::IterateResult iterateResult = TestCase::STOP;
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker     m_testCtx.touchWatchdog();
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker     try
361*35238bceSAndroid Build Coastguard Worker     {
362*35238bceSAndroid Build Coastguard Worker         iterateResult = m_caseExecutor->iterate(testCase);
363*35238bceSAndroid Build Coastguard Worker     }
364*35238bceSAndroid Build Coastguard Worker     catch (const std::bad_alloc &)
365*35238bceSAndroid Build Coastguard Worker     {
366*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Failed to allocate memory during test execution");
367*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(true);
368*35238bceSAndroid Build Coastguard Worker     }
369*35238bceSAndroid Build Coastguard Worker     catch (const tcu::TestException &e)
370*35238bceSAndroid Build Coastguard Worker     {
371*35238bceSAndroid Build Coastguard Worker         log << e;
372*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(e.getTestResult(), e.getMessage());
373*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(e.isFatal());
374*35238bceSAndroid Build Coastguard Worker     }
375*35238bceSAndroid Build Coastguard Worker     catch (const tcu::Exception &e)
376*35238bceSAndroid Build Coastguard Worker     {
377*35238bceSAndroid Build Coastguard Worker         log << e;
378*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage());
379*35238bceSAndroid Build Coastguard Worker     }
380*35238bceSAndroid Build Coastguard Worker 
381*35238bceSAndroid Build Coastguard Worker     return iterateResult;
382*35238bceSAndroid Build Coastguard Worker }
383*35238bceSAndroid Build Coastguard Worker 
384*35238bceSAndroid Build Coastguard Worker } // namespace tcu
385