diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp b/Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp new file mode 100644 index 000000000..3745bc3ce --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/tests/deqp_support/tcuRandomOrderExecutor.cpp @@ -0,0 +1,282 @@ +/*------------------------------------------------------------------------- + * drawElements Quality Program Tester Core + * ---------------------------------------- + * + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Executor which can run randomly accessed tests. + *//*--------------------------------------------------------------------*/ + +#include "tcuRandomOrderExecutor.h" + +#include "tcuCommandLine.hpp" +#include "tcuTestLog.hpp" +#include "deStringUtil.hpp" +#include "deClock.h" + +#include <cstdio> +#include <algorithm> +#include <fstream> + +using std::vector; +using std::string; + +namespace tcu +{ + +RandomOrderExecutor::RandomOrderExecutor(TestPackageRoot &root, TestContext &testCtx) + : m_testCtx(testCtx), m_inflater(testCtx) +{ + m_nodeStack.push_back(NodeStackEntry(&root)); + root.getChildren(m_nodeStack[0].children); +} + +RandomOrderExecutor::~RandomOrderExecutor(void) +{ + pruneStack(1); +} + +void RandomOrderExecutor::pruneStack(size_t newStackSize) +{ + // \note Root is not managed by us + DE_ASSERT(de::inRange(newStackSize, size_t(1), m_nodeStack.size())); + + while (m_nodeStack.size() > newStackSize) + { + NodeStackEntry &curEntry = m_nodeStack.back(); + const bool isPkg = curEntry.node->getNodeType() == NODETYPE_PACKAGE; + + DE_ASSERT((m_nodeStack.size() == 2) == isPkg); + + if (curEntry.node) // Just in case we are in + // cleanup path after partial + // prune + { + if (curEntry.node->getNodeType() == NODETYPE_GROUP) + m_inflater.leaveGroupNode(static_cast<TestCaseGroup *>(curEntry.node)); + else if (curEntry.node->getNodeType() == NODETYPE_PACKAGE) + m_inflater.leaveTestPackage(static_cast<TestPackage *>(curEntry.node)); + else + DE_ASSERT(curEntry.children.empty()); + + curEntry.node = DE_NULL; + curEntry.children.clear(); + } + + if (isPkg) + m_caseExecutor.clear(); + + m_nodeStack.pop_back(); + } +} + +static TestNode *findNodeByName(vector<TestNode *> &nodes, const std::string &name) +{ + for (vector<TestNode *>::const_iterator node = nodes.begin(); node != nodes.end(); ++node) + { + if (name == (*node)->getName()) + return *node; + } + + return DE_NULL; +} + +TestCase *RandomOrderExecutor::seekToCase(const string &path) +{ + const vector<string> components = de::splitString(path, '.'); + size_t compNdx; + + DE_ASSERT(!m_nodeStack.empty() && m_nodeStack.front().node->getNodeType() == NODETYPE_ROOT); + + for (compNdx = 0; compNdx < components.size(); compNdx++) + { + const size_t stackPos = compNdx + 1; + + if (stackPos >= m_nodeStack.size()) + break; // Stack end + else if (components[compNdx] != m_nodeStack[stackPos].node->getName()) + { + // Current stack doesn't match any more, prune. + pruneStack(stackPos); + break; + } + } + + DE_ASSERT(m_nodeStack.size() == compNdx + 1); + + for (; compNdx < components.size(); compNdx++) + { + const size_t parentStackPos = compNdx; + TestNode *const curNode = + findNodeByName(m_nodeStack[parentStackPos].children, components[compNdx]); + + if (!curNode) + throw Exception(string("Test hierarchy node not found: ") + path); + + m_nodeStack.push_back(NodeStackEntry(curNode)); + + if (curNode->getNodeType() == NODETYPE_PACKAGE) + { + TestPackage *const testPackage = static_cast<TestPackage *>(curNode); + + m_inflater.enterTestPackage(testPackage, m_nodeStack.back().children); + DE_ASSERT(!m_caseExecutor); + m_caseExecutor = de::MovePtr<TestCaseExecutor>(testPackage->createExecutor()); + } + else if (curNode->getNodeType() == NODETYPE_GROUP) + m_inflater.enterGroupNode(static_cast<TestCaseGroup *>(curNode), + m_nodeStack.back().children); + else if (compNdx + 1 != components.size()) + throw Exception(string("Invalid test hierarchy path: ") + path); + } + + DE_ASSERT(m_nodeStack.size() == components.size() + 1); + + if (isTestNodeTypeExecutable(m_nodeStack.back().node->getNodeType())) + return dynamic_cast<TestCase *>(m_nodeStack.back().node); + else + throw Exception(string("Not a test case: ") + path); +} + +static qpTestCaseType nodeTypeToTestCaseType(TestNodeType nodeType) +{ + switch (nodeType) + { + case NODETYPE_SELF_VALIDATE: + return QP_TEST_CASE_TYPE_SELF_VALIDATE; + case NODETYPE_PERFORMANCE: + return QP_TEST_CASE_TYPE_PERFORMANCE; + case NODETYPE_CAPABILITY: + return QP_TEST_CASE_TYPE_CAPABILITY; + case NODETYPE_ACCURACY: + return QP_TEST_CASE_TYPE_ACCURACY; + default: + DE_ASSERT(false); + return QP_TEST_CASE_TYPE_LAST; + } +} + +TestStatus RandomOrderExecutor::execute(const std::string &casePath) +{ + TestCase *const testCase = seekToCase(casePath); + TestLog &log = m_testCtx.getLog(); + const qpTestCaseType caseType = nodeTypeToTestCaseType(testCase->getNodeType()); + + m_testCtx.setTerminateAfter(false); + log.startCase(casePath.c_str(), caseType); + + { + const TestStatus result = executeInner(testCase, casePath); + log.endCase(result.getCode(), result.getDescription().c_str()); + return result; + } +} + +tcu::TestStatus RandomOrderExecutor::executeInner(TestCase *testCase, const std::string &casePath) +{ + TestLog &log = m_testCtx.getLog(); + const deUint64 testStartTime = deGetMicroseconds(); + + m_testCtx.setTestResult(QP_TEST_RESULT_LAST, ""); + + // Initialize, will return immediately if fails + try + { + m_caseExecutor->init(testCase, casePath); + } + catch (const std::bad_alloc &) + { + m_testCtx.setTerminateAfter(true); + return TestStatus(QP_TEST_RESULT_RESOURCE_ERROR, + "Failed to allocate memory in test case init"); + } + catch (const TestException &e) + { + DE_ASSERT(e.getTestResult() != QP_TEST_RESULT_LAST); + m_testCtx.setTerminateAfter(e.isFatal()); + log << e; + return TestStatus(e.getTestResult(), e.getMessage()); + } + catch (const Exception &e) + { + log << e; + return TestStatus(QP_TEST_RESULT_FAIL, e.getMessage()); + } + + // Execute + for (;;) + { + TestCase::IterateResult iterateResult = TestCase::STOP; + + m_testCtx.touchWatchdog(); + + try + { + iterateResult = m_caseExecutor->iterate(testCase); + } + catch (const std::bad_alloc &) + { + m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, + "Failed to allocate memory during test " + "execution"); + } + catch (const TestException &e) + { + log << e; + m_testCtx.setTestResult(e.getTestResult(), e.getMessage()); + m_testCtx.setTerminateAfter(e.isFatal()); + } + catch (const Exception &e) + { + log << e; + m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage()); + } + + if (iterateResult == TestCase::STOP) + break; + } + + DE_ASSERT(m_testCtx.getTestResult() != QP_TEST_RESULT_LAST); + + if (m_testCtx.getTestResult() == QP_TEST_RESULT_RESOURCE_ERROR) + m_testCtx.setTerminateAfter(true); + + // De-initialize + try + { + m_caseExecutor->deinit(testCase); + } + catch (const tcu::Exception &e) + { + log << e << TestLog::Message << "Error in test case deinit, test program " + "will terminate." + << TestLog::EndMessage; + m_testCtx.setTerminateAfter(true); + } + + if (m_testCtx.getWatchDog()) + qpWatchDog_reset(m_testCtx.getWatchDog()); + + { + const TestStatus result = + TestStatus(m_testCtx.getTestResult(), m_testCtx.getTestResultDesc()); + m_testCtx.setTestResult(QP_TEST_RESULT_LAST, ""); + return result; + } +} + +} // tcu |