13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Class for executing tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestExecutor.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPlatform.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <typeinfo>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdio.h>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdlib.h>
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string.h>
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestExecutor::TestExecutor (TestContext& testCtx, const CommandLine& cmdLine)
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_testCtx				(testCtx)
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_cmdLine				(cmdLine)
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rootNode			(DE_NULL)
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testCaseWrapper		(DE_NULL)
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testCaseListFile	(DE_NULL)
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_testCaseListWriter	(DE_NULL)
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_abortSession	= false;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_isInTestCase	= false;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create the root node.
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestPackageRegistry*						packageRegistry	= TestPackageRegistry::getSingleton();
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<TestPackageRegistry::PackageInfo*>	packageInfos	= packageRegistry->getPackageInfos();
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<TestNode*>							testPackages;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)packageInfos.size(); i++)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		testPackages.push_back(packageInfos[i]->createFunc(testCtx));
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rootNode = new TestPackageRoot(testCtx, testPackages);
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Init traverse stack.
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NodeIter iter(m_rootNode);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_sessionStack.push_back(iter);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestExecutor::~TestExecutor (void)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testCaseListWriter)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpXmlWriter_destroy(m_testCaseListWriter);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_testCaseListFile)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fclose(m_testCaseListFile);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_rootNode;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test sub-case iteration.
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestExecutor::enterTestPackage (TestPackage* testPackage, const char* packageName)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(testPackage && packageName);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Open file/writer for case dumping.
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RunMode runMode = m_cmdLine.getRunMode();
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (runMode == RUNMODE_DUMP_XML_CASELIST || runMode == RUNMODE_DUMP_TEXT_CASELIST)
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const	ext				= (runMode == RUNMODE_DUMP_XML_CASELIST) ? "xml" : "txt";
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		fileName		= string(packageName) + "-cases." + ext;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		print("Dumping all test case names in '%s' to file '%s'..\n", packageName, fileName.c_str());
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(m_testCaseListFile = fopen(fileName.c_str(), "wb"));
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (runMode == RUNMODE_DUMP_XML_CASELIST)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(m_testCaseListWriter = qpXmlWriter_createFileWriter(m_testCaseListFile, DE_FALSE));
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			qpXmlWriter_startDocument(m_testCaseListWriter);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			qpXmlWriter_startElement(m_testCaseListWriter, "TestCaseList", 0, DE_NULL);
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize package.
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	testPackage->init();
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Store test case wrapper
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCaseWrapper = &testPackage->getTestCaseWrapper();
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_testCaseWrapper);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set archive.
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setCurrentArchive(testPackage->getArchive());
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestExecutor::leaveTestPackage (TestPackage* testPackage)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(testPackage);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RunMode runMode = m_cmdLine.getRunMode();
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (runMode == RUNMODE_DUMP_XML_CASELIST)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpXmlWriter_endElement(m_testCaseListWriter, "TestCaseList");
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpXmlWriter_endDocument(m_testCaseListWriter);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		qpXmlWriter_destroy(m_testCaseListWriter);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCaseListWriter = DE_NULL;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (runMode == RUNMODE_DUMP_TEXT_CASELIST || runMode == RUNMODE_DUMP_XML_CASELIST)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fclose(m_testCaseListFile);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCaseListFile = DE_NULL;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_testCaseListWriter && !m_testCaseListFile);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCaseWrapper = DE_NULL;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setCurrentArchive(m_testCtx.getRootArchive());
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Deinitialize package.
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	testPackage->deinit();
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestExecutor::enterGroupNode (TestCaseGroup* testGroup, const char* casePath)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(casePath);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	testGroup->init();
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestExecutor::leaveGroupNode (TestCaseGroup* testGroup)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	testGroup->deinit();
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic qpTestCaseType nodeTypeToTestCaseType (TestNodeType nodeType)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (nodeType)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case NODETYPE_SELF_VALIDATE:	return QP_TEST_CASE_TYPE_SELF_VALIDATE;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case NODETYPE_PERFORMANCE:		return QP_TEST_CASE_TYPE_PERFORMANCE;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case NODETYPE_CAPABILITY:		return QP_TEST_CASE_TYPE_CAPABILITY;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case NODETYPE_ACCURACY:			return QP_TEST_CASE_TYPE_ACCURACY;
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return QP_TEST_CASE_TYPE_LAST;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TestExecutor::enterTestCase (TestCase* testCase, const char* casePath)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RunMode			runMode		= m_cmdLine.getRunMode();
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const qpTestCaseType	caseType	= nodeTypeToTestCaseType(testCase->getNodeType());
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (runMode == RUNMODE_EXECUTE)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		print("\nTest case '%s'..\n", casePath);
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog().startCase(casePath, caseType);
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_isInTestCase = true;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_LAST, "");
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_testCaseWrapper->initTestCase(testCase))
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_testCtx.getTestResult() == QP_TEST_RESULT_LAST)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Unexpected error in subcase init");
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestExecutor::leaveTestCase (TestCase* testCase)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const RunMode runMode = m_cmdLine.getRunMode();
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (runMode == RUNMODE_EXECUTE)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1979296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		// De-init case.
1989296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		const bool			deinitOk		= m_testCaseWrapper->deinitTestCase(testCase);
1999296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		const qpTestResult	testResult		= m_testCtx.getTestResult();
2009296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		const char* const	testResultDesc	= m_testCtx.getTestResultDesc();
2019296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		const bool			terminateAfter	= m_testCtx.getTerminateAfter();
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(testResult != QP_TEST_RESULT_LAST);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2049296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		m_isInTestCase = false;
2059296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		m_testCtx.getLog().endCase(testResult, testResultDesc);
2069296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry
2079296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		// Update statistics.
2089296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		print("  %s (%s)\n", qpGetTestResultName(testResult), testResultDesc);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_result.numExecuted += 1;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (testResult)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case QP_TEST_RESULT_PASS:					m_result.numPassed			+= 1;	break;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case QP_TEST_RESULT_NOT_SUPPORTED:			m_result.numNotSupported	+= 1;	break;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case QP_TEST_RESULT_QUALITY_WARNING:		m_result.numWarnings		+= 1;	break;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case QP_TEST_RESULT_COMPATIBILITY_WARNING:	m_result.numWarnings		+= 1;	break;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:									m_result.numFailed			+= 1;	break;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2209296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		// terminateAfter, Resource error or any error in deinit means that execution should end
2219296957fdb746e7558a00fec7f9a519f092168d8Jarkko Pöyry		if (terminateAfter || !deinitOk || testResult == QP_TEST_RESULT_RESOURCE_ERROR)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_abortSession = true;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [2011-02-09 pyry] Disable watchdog temporarily?
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_testCtx.getWatchDog())
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			qpWatchDog_reset(m_testCtx.getWatchDog());
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Return true while session should still continue, false otherwise.
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TestExecutor::iterate (void)
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (!m_sessionStack.empty())
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Get full path to node.
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string nodePath = "";
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < (int)m_sessionStack.size(); ndx++)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				NodeIter& iter = m_sessionStack[ndx];
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (ndx > 1) // ignore root package
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					nodePath += ".";
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				nodePath += iter.node->getName();
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Handle the node.
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			NodeIter& iter = m_sessionStack[m_sessionStack.size()-1];
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(iter.node != DE_NULL);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestNode*		node	= iter.node;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool			isLeaf	= isTestNodeTypeExecutable(node->getNodeType());
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (iter.getState())
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case NodeIter::STATE_BEGIN:
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Return to parent if name doesn't match filter.
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!(isLeaf ? m_cmdLine.checkTestCaseName(nodePath.c_str()) : m_cmdLine.checkTestGroupName(nodePath.c_str())))
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_sessionStack.pop_back();
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Enter node.
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					bool enterOk = true;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					switch (node->getNodeType())
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_ROOT:				/* nada */																	break;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_PACKAGE:			enterTestPackage(static_cast<TestPackage*>(node), nodePath.c_str());		break;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_GROUP:			enterGroupNode(static_cast<TestCaseGroup*>(node), nodePath.c_str());		break;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_PERFORMANCE:
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_CAPABILITY:
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_ACCURACY:			/* fall-trough */
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_SELF_VALIDATE:	enterOk = enterTestCase(static_cast<TestCase*>(node), nodePath.c_str());	break;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						default: DE_ASSERT(false);
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (m_cmdLine.getRunMode() == RUNMODE_EXECUTE)
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (isLeaf)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							if (enterOk)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								iter.setState(NodeIter::STATE_EXECUTE_TEST);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							else
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								iter.setState(NodeIter::STATE_FINISH);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						else
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							iter.setState(NodeIter::STATE_TRAVERSE_CHILDREN);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else if (m_cmdLine.getRunMode() == RUNMODE_DUMP_XML_CASELIST)
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (node->getNodeType() != NODETYPE_ROOT && node->getNodeType() != NODETYPE_PACKAGE)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							string			caseName	= iter.node->getName();
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							string			description	= iter.node->getDescription();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							qpXmlAttribute	attribs[8];
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							int				numAttribs = 0;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char*		caseType	= DE_NULL;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							switch (node->getNodeType())
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								case NODETYPE_SELF_VALIDATE:	caseType = "SelfValidate";	break;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								case NODETYPE_CAPABILITY:		caseType = "Capability";	break;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								case NODETYPE_ACCURACY:			caseType = "Accuracy";		break;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								case NODETYPE_PERFORMANCE:		caseType = "Performance";	break;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								default:						caseType = "TestGroup";		break;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							attribs[numAttribs++] = qpSetStringAttrib("Name", caseName.c_str());
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							attribs[numAttribs++] = qpSetStringAttrib("CaseType", caseType);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							attribs[numAttribs++] = qpSetStringAttrib("Description", description.c_str());
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							qpXmlWriter_startElement(m_testCaseListWriter, "TestCase", numAttribs, attribs);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						iter.setState(isLeaf ? NodeIter::STATE_FINISH : NodeIter::STATE_TRAVERSE_CHILDREN);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else if (m_cmdLine.getRunMode() == RUNMODE_DUMP_TEXT_CASELIST)
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// \note Case list file is not open until we are in test package.
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (isLeaf)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							fprintf(m_testCaseListFile, "TEST: %s\n", nodePath.c_str());
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						else if (node->getNodeType() != NODETYPE_ROOT)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							fprintf(m_testCaseListFile, "GROUP: %s\n", nodePath.c_str());
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						iter.setState(isLeaf ? NodeIter::STATE_FINISH : NodeIter::STATE_TRAVERSE_CHILDREN);
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case NodeIter::STATE_EXECUTE_TEST:
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Touch the watchdog.
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.touchWatchdog();
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Iterate the sub-case.
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCase::IterateResult iterateResult = m_testCaseWrapper->iterateTestCase(static_cast<TestCase*>(node));
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (iterateResult == TestCase::STOP)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						iter.setState(NodeIter::STATE_FINISH);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return true; // return after each iteration (when another iteration follows).
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case NodeIter::STATE_TRAVERSE_CHILDREN:
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int numChildren = (int)iter.children.size();
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (++iter.curChildNdx < numChildren)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Push child to stack.
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestNode* childNode = iter.children[iter.curChildNdx];
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_sessionStack.push_back(NodeIter(childNode));
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						iter.setState(NodeIter::STATE_FINISH);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case NodeIter::STATE_FINISH:
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (m_cmdLine.getRunMode() == RUNMODE_DUMP_XML_CASELIST)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (node->getNodeType() != NODETYPE_ROOT && node->getNodeType() != NODETYPE_PACKAGE)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							qpXmlWriter_endElement(m_testCaseListWriter, "TestCase");
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Leave node.
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					switch (node->getNodeType())
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_ROOT:				/* nada */											break;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_PACKAGE:			leaveTestPackage(static_cast<TestPackage*>(node));	break;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_GROUP:			leaveGroupNode(static_cast<TestCaseGroup*>(node));	break;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_ACCURACY:
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_CAPABILITY:
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_PERFORMANCE:		/* fall-thru */
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						case NODETYPE_SELF_VALIDATE:	leaveTestCase(static_cast<TestCase*>(node));		break;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						default: DE_ASSERT(false);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_sessionStack.pop_back();
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Return if execution should abort.
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (m_abortSession)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Otherwise continue iterating.
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(DE_FALSE);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception& e)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		print("TestExecutor::iterateSession(): Caught unhandled %s: %s\n", typeid(e).name(), e.what());
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_result.isComplete = true;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
409