From 4e3ea87b79b12195e79d28ef6ab2be0a847b5d9a Mon Sep 17 00:00:00 2001 From: Pyry Haulos Date: Fri, 20 Mar 2015 11:06:41 -0700 Subject: [PATCH] Refactor tcu::TestExecutor tcu::TestExecutor used to provide all functionality required for traversing hierarchy, executing tests, and even generating test case lists. This change splits TestExecutor into three separate utilities: 1) TestHierarchyIterator provides test hierarchy traversal. 2) TestSessionExecutor provides test session execution. 3) Utility functions for generating test case list files. In addition TestCaseWrapper has been replaced by package-specific TestCaseExecutor with TestSessionExecutor-managed lifetime. Change-Id: Idb8090964a80cd64892231798710547e84e2989b --- Android.mk | 13 +- framework/common/CMakeLists.txt | 10 +- framework/common/tcuApp.cpp | 70 ++-- framework/common/tcuApp.hpp | 18 +- framework/common/tcuResource.cpp | 7 - framework/common/tcuResultCollector.hpp | 1 - framework/common/tcuTestCase.hpp | 18 + framework/common/tcuTestCaseWrapper.cpp | 135 ------- framework/common/tcuTestContext.hpp | 5 +- framework/common/tcuTestExecutor.cpp | 408 --------------------- framework/common/tcuTestExecutor.hpp | 174 --------- framework/common/tcuTestHierarchyIterator.cpp | 259 +++++++++++++ framework/common/tcuTestHierarchyIterator.hpp | 202 ++++++++++ framework/common/tcuTestHierarchyUtil.cpp | 196 ++++++++++ ...estCaseWrapper.hpp => tcuTestHierarchyUtil.hpp} | 30 +- framework/common/tcuTestPackage.cpp | 9 + framework/common/tcuTestPackage.hpp | 53 ++- framework/common/tcuTestSessionExecutor.cpp | 292 +++++++++++++++ framework/common/tcuTestSessionExecutor.hpp | 102 ++++++ modules/egl/teglTestPackage.cpp | 79 ++-- modules/egl/teglTestPackage.hpp | 33 +- modules/gles2/CMakeLists.txt | 2 - modules/gles2/tes2TestCaseWrapper.cpp | 110 ------ modules/gles2/tes2TestCaseWrapper.hpp | 54 --- modules/gles2/tes2TestPackage.cpp | 116 ++++-- modules/gles2/tes2TestPackage.hpp | 23 +- modules/gles3/CMakeLists.txt | 2 - modules/gles3/tes3TestCaseWrapper.cpp | 110 ------ modules/gles3/tes3TestCaseWrapper.hpp | 54 --- modules/gles3/tes3TestPackage.cpp | 114 ++++-- modules/gles3/tes3TestPackage.hpp | 23 +- modules/gles31/CMakeLists.txt | 2 - modules/gles31/tes31TestCase.cpp | 4 +- modules/gles31/tes31TestCaseWrapper.cpp | 101 ----- modules/gles31/tes31TestCaseWrapper.hpp | 54 --- modules/gles31/tes31TestPackage.cpp | 98 +++-- modules/gles31/tes31TestPackage.hpp | 23 +- modules/internal/ditImageCompareTests.cpp | 2 +- modules/internal/ditImageIOTests.cpp | 8 +- modules/internal/ditTestPackage.cpp | 32 +- modules/internal/ditTestPackage.hpp | 7 +- 41 files changed, 1535 insertions(+), 1518 deletions(-) delete mode 100644 framework/common/tcuTestCaseWrapper.cpp delete mode 100644 framework/common/tcuTestExecutor.cpp delete mode 100644 framework/common/tcuTestExecutor.hpp create mode 100644 framework/common/tcuTestHierarchyIterator.cpp create mode 100644 framework/common/tcuTestHierarchyIterator.hpp create mode 100644 framework/common/tcuTestHierarchyUtil.cpp rename framework/common/{tcuTestCaseWrapper.hpp => tcuTestHierarchyUtil.hpp} (59%) create mode 100644 framework/common/tcuTestSessionExecutor.cpp create mode 100644 framework/common/tcuTestSessionExecutor.hpp delete mode 100644 modules/gles2/tes2TestCaseWrapper.cpp delete mode 100644 modules/gles2/tes2TestCaseWrapper.hpp delete mode 100644 modules/gles3/tes3TestCaseWrapper.cpp delete mode 100644 modules/gles3/tes3TestCaseWrapper.hpp delete mode 100644 modules/gles31/tes31TestCaseWrapper.cpp delete mode 100644 modules/gles31/tes31TestCaseWrapper.hpp diff --git a/Android.mk b/Android.mk index 2868a95..2115e14 100644 --- a/Android.mk +++ b/Android.mk @@ -38,6 +38,7 @@ LOCAL_SRC_FILES := \ framework/common/tcuCompressedTexture.cpp \ framework/common/tcuCPUWarmup.cpp \ framework/common/tcuDefs.cpp \ + framework/common/tcuEither.cpp \ framework/common/tcuFactoryRegistry.cpp \ framework/common/tcuFloat.cpp \ framework/common/tcuFloatFormat.cpp \ @@ -47,29 +48,29 @@ LOCAL_SRC_FILES := \ framework/common/tcuImageIO.cpp \ framework/common/tcuInterval.cpp \ framework/common/tcuMatrix.cpp \ + framework/common/tcuMaybe.cpp \ framework/common/tcuPlatform.cpp \ framework/common/tcuRandomValueIterator.cpp \ framework/common/tcuRenderTarget.cpp \ framework/common/tcuResource.cpp \ framework/common/tcuResultCollector.cpp \ framework/common/tcuRGBA.cpp \ - framework/common/tcuEither.cpp \ + framework/common/tcuSeedBuilder.cpp \ framework/common/tcuStringTemplate.cpp \ framework/common/tcuSurface.cpp \ framework/common/tcuTestCase.cpp \ - framework/common/tcuTestCaseWrapper.cpp \ framework/common/tcuTestContext.cpp \ - framework/common/tcuTestExecutor.cpp \ + framework/common/tcuTestHierarchyIterator.cpp \ + framework/common/tcuTestHierarchyUtil.cpp \ framework/common/tcuTestLog.cpp \ framework/common/tcuTestPackage.cpp \ + framework/common/tcuTestSessionExecutor.cpp \ framework/common/tcuTexCompareVerifier.cpp \ framework/common/tcuTexLookupVerifier.cpp \ framework/common/tcuTexture.cpp \ framework/common/tcuTextureUtil.cpp \ framework/common/tcuTexVerifierUtil.cpp \ framework/common/tcuThreadUtil.cpp \ - framework/common/tcuSeedBuilder.cpp \ - framework/common/tcuMaybe.cpp \ framework/delibs/debase/deDefs.c \ framework/delibs/debase/deFloat16.c \ framework/delibs/debase/deInt32.c \ @@ -324,7 +325,6 @@ LOCAL_SRC_FILES := \ modules/gles31/tes31Context.cpp \ modules/gles31/tes31InfoTests.cpp \ modules/gles31/tes31TestCase.cpp \ - modules/gles31/tes31TestCaseWrapper.cpp \ modules/gles31/tes31TestPackage.cpp \ modules/gles31/tes31TestPackageEntry.cpp \ modules/gles3/accuracy/es3aAccuracyTests.cpp \ @@ -463,7 +463,6 @@ LOCAL_SRC_FILES := \ modules/gles3/tes3Context.cpp \ modules/gles3/tes3InfoTests.cpp \ modules/gles3/tes3TestCase.cpp \ - modules/gles3/tes3TestCaseWrapper.cpp \ modules/gles3/tes3TestPackage.cpp \ modules/gles3/tes3TestPackageEntry.cpp \ modules/glshared/glsAttributeLocationTests.cpp \ diff --git a/framework/common/CMakeLists.txt b/framework/common/CMakeLists.txt index 20ad1dc..9529b56 100644 --- a/framework/common/CMakeLists.txt +++ b/framework/common/CMakeLists.txt @@ -46,12 +46,10 @@ set(TCUTIL_SRCS tcuSurface.hpp tcuTestCase.cpp tcuTestCase.hpp - tcuTestCaseWrapper.cpp - tcuTestCaseWrapper.hpp tcuTestContext.cpp tcuTestContext.hpp - tcuTestExecutor.cpp - tcuTestExecutor.hpp + tcuTestSessionExecutor.cpp + tcuTestSessionExecutor.hpp tcuTestLog.cpp tcuTestLog.hpp tcuTestPackage.cpp @@ -85,6 +83,10 @@ set(TCUTIL_SRCS tcuMaybe.cpp tcuEither.hpp tcuEither.cpp + tcuTestHierarchyIterator.cpp + tcuTestHierarchyIterator.hpp + tcuTestHierarchyUtil.cpp + tcuTestHierarchyUtil.hpp ) set(TCUTIL_LIBS diff --git a/framework/common/tcuApp.cpp b/framework/common/tcuApp.cpp index 0981044..a16e45e 100644 --- a/framework/common/tcuApp.cpp +++ b/framework/common/tcuApp.cpp @@ -24,7 +24,8 @@ #include "tcuApp.hpp" #include "tcuPlatform.hpp" #include "tcuTestContext.hpp" -#include "tcuTestExecutor.hpp" +#include "tcuTestSessionExecutor.hpp" +#include "tcuTestHierarchyUtil.hpp" #include "tcuCommandLine.hpp" #include "tcuTestLog.hpp" #include "qpInfo.h" @@ -34,19 +35,6 @@ namespace tcu { -static void watchDogTimeoutFunc (qpWatchDog* watchDog, void* userPtr) -{ - DE_UNREF(watchDog); - static_cast(userPtr)->onWatchdogTimeout(); -} - -static void crashHandlerFunc (qpCrashHandler* crashHandler, void* userPtr) -{ - DE_UNREF(crashHandler); - static_cast(userPtr)->onCrash(); -} - - /*--------------------------------------------------------------------*//*! * \brief Construct test application * @@ -61,6 +49,7 @@ App::App (Platform& platform, Archive& archive, TestLog& log, const CommandLine& , m_crashHandler (DE_NULL) , m_crashed (false) , m_testCtx (DE_NULL) + , m_testRoot (DE_NULL) , m_testExecutor (DE_NULL) { print("dEQP Core %s (0x%08x) starting..\n", qpGetReleaseName(), qpGetReleaseId()); @@ -71,29 +60,48 @@ App::App (Platform& platform, Archive& archive, TestLog& log, const CommandLine& try { + const RunMode runMode = cmdLine.getRunMode(); + // Initialize watchdog if (cmdLine.isWatchDogEnabled()) - TCU_CHECK(m_watchDog = qpWatchDog_create(watchDogTimeoutFunc, this, 300, 30)); + TCU_CHECK_INTERNAL(m_watchDog = qpWatchDog_create(onWatchdogTimeout, this, 300, 30)); // Initialize crash handler. if (cmdLine.isCrashHandlingEnabled()) - TCU_CHECK(m_crashHandler = qpCrashHandler_create(crashHandlerFunc, this)); + TCU_CHECK_INTERNAL(m_crashHandler = qpCrashHandler_create(onCrash, this)); // Create test context m_testCtx = new TestContext(m_platform, archive, log, cmdLine, m_watchDog); - // Create test executor - m_testExecutor = new TestExecutor(*m_testCtx, cmdLine); + // Create root from registry + m_testRoot = new TestPackageRoot(*m_testCtx, TestPackageRegistry::getSingleton()); + + // \note No executor is created if runmode is not EXECUTE + if (runMode == RUNMODE_EXECUTE) + m_testExecutor = new TestSessionExecutor(*m_testRoot, *m_testCtx); + else if (runMode == RUNMODE_DUMP_XML_CASELIST) + writeXmlCaselists(*m_testRoot, *m_testCtx, m_testCtx->getCommandLine()); + else if (runMode == RUNMODE_DUMP_TEXT_CASELIST) + writeTxtCaselists(*m_testRoot, *m_testCtx, m_testCtx->getCommandLine()); + else + DE_ASSERT(false); } catch (const std::exception& e) { + cleanup(); die("Failed to initialize dEQP: %s", e.what()); } } App::~App (void) { + cleanup(); +} + +void App::cleanup (void) +{ delete m_testExecutor; + delete m_testRoot; delete m_testCtx; if (m_crashHandler) @@ -103,7 +111,6 @@ App::~App (void) qpWatchDog_destroy(m_watchDog); } - /*--------------------------------------------------------------------*//*! * \brief Step forward test execution * \return true if application should call iterate() again and false @@ -111,8 +118,14 @@ App::~App (void) *//*--------------------------------------------------------------------*/ bool App::iterate (void) { + if (!m_testExecutor) + { + DE_ASSERT(m_testCtx->getCommandLine().getRunMode() != RUNMODE_EXECUTE); + return false; + } + // Poll platform events - bool platformOk = m_platform.processEvents(); + const bool platformOk = m_platform.processEvents(); // Iterate a step. bool testExecOk = false; @@ -138,7 +151,7 @@ bool App::iterate (void) const RunMode runMode = m_testCtx->getCommandLine().getRunMode(); if (runMode == RUNMODE_EXECUTE) { - const TestRunResult& result = m_testExecutor->getResult(); + const TestRunStatus& result = m_testExecutor->getStatus(); // Report statistics. print("\nTest run totals:\n"); @@ -154,13 +167,16 @@ bool App::iterate (void) return platformOk && testExecOk; } -/*--------------------------------------------------------------------*//*! - * \brief Get test run result - * \return Current test run result. - *//*--------------------------------------------------------------------*/ -const TestRunResult& App::getResult (void) const +void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr) { - return m_testExecutor->getResult(); + DE_UNREF(watchDog); + static_cast(userPtr)->onWatchdogTimeout(); +} + +void App::onCrash (qpCrashHandler* crashHandler, void* userPtr) +{ + DE_UNREF(crashHandler); + static_cast(userPtr)->onCrash(); } void App::onWatchdogTimeout (void) diff --git a/framework/common/tcuApp.hpp b/framework/common/tcuApp.hpp index 22e5606..8233eb3 100644 --- a/framework/common/tcuApp.hpp +++ b/framework/common/tcuApp.hpp @@ -37,12 +37,10 @@ namespace tcu class Archive; class Platform; class TestContext; -class TestExecutor; +class TestSessionExecutor; class CommandLine; class TestLog; - -// Defined in tcuTestExecutor.hpp -class TestRunResult; +class TestPackageRoot; /*--------------------------------------------------------------------*//*! * \brief Test application @@ -58,7 +56,7 @@ class TestRunResult; * App is responsible of setting up crash handler (qpCrashHandler) and * watchdog (qpWatchDog). * - * See tcuMain.cpp for example on how to implement application stub. + * See tcuMain.cpp for an example on how to implement application stub. *//*--------------------------------------------------------------------*/ class App { @@ -68,12 +66,15 @@ public: bool iterate (void); - const TestRunResult& getResult (void) const; +protected: + void cleanup (void); void onWatchdogTimeout (void); void onCrash (void); -protected: + static void onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr); + static void onCrash (qpCrashHandler* crashHandler, void* userPtr); + Platform& m_platform; qpWatchDog* m_watchDog; qpCrashHandler* m_crashHandler; @@ -81,7 +82,8 @@ protected: bool m_crashed; TestContext* m_testCtx; - TestExecutor* m_testExecutor; + TestPackageRoot* m_testRoot; + TestSessionExecutor* m_testExecutor; }; } // tcu diff --git a/framework/common/tcuResource.cpp b/framework/common/tcuResource.cpp index 648798c..5ecc597 100644 --- a/framework/common/tcuResource.cpp +++ b/framework/common/tcuResource.cpp @@ -51,13 +51,6 @@ FileResource::FileResource (const char* filename) m_file = fopen(filename, "rb"); if (!m_file) throw ResourceError("Failed to open file", filename, __FILE__, __LINE__); - -/* { - FILE* log = fopen("resources.log", "a"); - fprintf(log, "%s\n", filename); - fflush(log); - fclose(log); - }*/ } FileResource::~FileResource () diff --git a/framework/common/tcuResultCollector.hpp b/framework/common/tcuResultCollector.hpp index 6398f0a..d4af499 100644 --- a/framework/common/tcuResultCollector.hpp +++ b/framework/common/tcuResultCollector.hpp @@ -63,7 +63,6 @@ private: std::string m_message; } DE_WARN_UNUSED_TYPE; - } // tcu #endif // _TCURESULTCOLLECTOR_HPP \ No newline at end of file diff --git a/framework/common/tcuTestCase.hpp b/framework/common/tcuTestCase.hpp index 9ce5271..4543ca7 100644 --- a/framework/common/tcuTestCase.hpp +++ b/framework/common/tcuTestCase.hpp @@ -176,6 +176,24 @@ public: virtual ~TestCase (void); }; +class TestStatus +{ +public: + TestStatus (qpTestResult code, const std::string& description) : m_code(code), m_description(description) {} + + bool isComplete (void) const { return getCode() != QP_TEST_RESULT_LAST; } + qpTestResult getCode (void) const { DE_ASSERT(isComplete()); return m_code; } + const std::string& getDescription (void) const { DE_ASSERT(isComplete()); return m_description; } + + static TestStatus pass (const std::string& description) { return TestStatus(QP_TEST_RESULT_PASS, description); } + static TestStatus fail (const std::string& description) { return TestStatus(QP_TEST_RESULT_FAIL, description); } + static TestStatus incomplete (void) { return TestStatus(QP_TEST_RESULT_LAST, ""); } + +private: + qpTestResult m_code; + std::string m_description; +} DE_WARN_UNUSED_TYPE; + } // tcu #endif // _TCUTESTCASE_HPP diff --git a/framework/common/tcuTestCaseWrapper.cpp b/framework/common/tcuTestCaseWrapper.cpp deleted file mode 100644 index b8e2eb5..0000000 --- a/framework/common/tcuTestCaseWrapper.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/*------------------------------------------------------------------------- - * 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 Test case wrapper for test execution. - *//*--------------------------------------------------------------------*/ - -#include "tcuTestCaseWrapper.hpp" -#include "tcuTestLog.hpp" -#include "deClock.h" - -namespace tcu -{ - -TestCaseWrapper::TestCaseWrapper (TestContext& testCtx) - : m_testCtx (testCtx) - , m_testStartTime (0) -{ -} - -TestCaseWrapper::~TestCaseWrapper (void) -{ -} - -bool TestCaseWrapper::initTestCase (TestCase* testCase) -{ - // Initialize test case. - TestLog& log = m_testCtx.getLog(); - bool success = false; - - // Record test start time. - m_testStartTime = deGetMicroseconds(); - - try - { - testCase->init(); - success = true; - } - catch (const std::bad_alloc&) - { - DE_ASSERT(!success); - m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Failed to allocate memory in test case init"); - m_testCtx.setTerminateAfter(true); - } - catch (const tcu::TestException& e) - { - DE_ASSERT(!success); - m_testCtx.setTestResult(e.getTestResult(), e.getMessage()); - m_testCtx.setTerminateAfter(e.isFatal()); - log << e; - } - catch (const tcu::Exception& e) - { - DE_ASSERT(!success); - m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage()); - log << e; - } - - DE_ASSERT(success || m_testCtx.getTestResult() != QP_TEST_RESULT_LAST); - - return success; -} - -bool TestCaseWrapper::deinitTestCase (TestCase* testCase) -{ - bool deinitOk = false; - - // De-init case. - try - { - testCase->deinit(); - deinitOk = true; - } - catch (const tcu::Exception& e) - { - m_testCtx.getLog() << e - << TestLog::Message << "Error in test case deinit, test program will terminate." << TestLog::EndMessage; - } - - { - const deInt64 duration = deGetMicroseconds()-m_testStartTime; - m_testStartTime = 0; - m_testCtx.getLog() << TestLog::Integer("TestDuration", "Test case duration in microseconds", "us", QP_KEY_TAG_TIME, duration); - } - - return deinitOk; -} - -TestNode::IterateResult TestCaseWrapper::iterateTestCase (TestCase* testCase) -{ - // Iterate the sub-case. - TestLog& log = m_testCtx.getLog(); - TestCase::IterateResult iterateResult = TestCase::STOP; - - try - { - iterateResult = testCase->iterate(); - } - catch (const std::bad_alloc&) - { - m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Failed to allocate memory during test execution"); - m_testCtx.setTerminateAfter(true); - } - catch (const tcu::TestException& e) - { - log << e; - m_testCtx.setTestResult(e.getTestResult(), e.getMessage()); - m_testCtx.setTerminateAfter(e.isFatal()); - } - catch (const tcu::Exception& e) - { - log << e; - m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage()); - } - - return iterateResult; -} - -} // tcu diff --git a/framework/common/tcuTestContext.hpp b/framework/common/tcuTestContext.hpp index 3aa474d..2bf4ed3 100644 --- a/framework/common/tcuTestContext.hpp +++ b/framework/common/tcuTestContext.hpp @@ -69,7 +69,11 @@ public: void setTerminateAfter (bool terminate) { m_terminateAfter = terminate; } bool getTerminateAfter (void) const { return m_terminateAfter; } + protected: + TestContext (const TestContext&); + TestContext& operator= (const TestContext&); + Platform& m_platform; //!< Platform port implementation. Archive& m_rootArchive; //!< Root archive. TestLog& m_log; //!< Test log. @@ -82,7 +86,6 @@ protected: bool m_terminateAfter; //!< Should tester terminate after execution of the current test }; - } // tcu #endif // _TCUTESTCONTEXT_HPP diff --git a/framework/common/tcuTestExecutor.cpp b/framework/common/tcuTestExecutor.cpp deleted file mode 100644 index 69500a2..0000000 --- a/framework/common/tcuTestExecutor.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/*------------------------------------------------------------------------- - * 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 Class for executing tests. - *//*--------------------------------------------------------------------*/ - -#include "tcuTestExecutor.hpp" -#include "tcuCommandLine.hpp" -#include "tcuPlatform.hpp" -#include "tcuTestLog.hpp" - -#include "deInt32.h" - -#include - -#include -#include -#include - -using std::string; -using std::vector; - -namespace tcu -{ - -TestExecutor::TestExecutor (TestContext& testCtx, const CommandLine& cmdLine) - : m_testCtx (testCtx) - , m_cmdLine (cmdLine) - , m_rootNode (DE_NULL) - , m_testCaseWrapper (DE_NULL) - , m_testCaseListFile (DE_NULL) - , m_testCaseListWriter (DE_NULL) -{ - m_abortSession = false; - m_isInTestCase = false; - - // Create the root node. - TestPackageRegistry* packageRegistry = TestPackageRegistry::getSingleton(); - vector packageInfos = packageRegistry->getPackageInfos(); - vector testPackages; - - for (int i = 0; i < (int)packageInfos.size(); i++) - testPackages.push_back(packageInfos[i]->createFunc(testCtx)); - - m_rootNode = new TestPackageRoot(testCtx, testPackages); - - // Init traverse stack. - NodeIter iter(m_rootNode); - m_sessionStack.push_back(iter); -} - -TestExecutor::~TestExecutor (void) -{ - if (m_testCaseListWriter) - qpXmlWriter_destroy(m_testCaseListWriter); - - if (m_testCaseListFile) - fclose(m_testCaseListFile); - - delete m_rootNode; -} - -// Test sub-case iteration. -void TestExecutor::enterTestPackage (TestPackage* testPackage, const char* packageName) -{ - DE_ASSERT(testPackage && packageName); - - // Open file/writer for case dumping. - const RunMode runMode = m_cmdLine.getRunMode(); - if (runMode == RUNMODE_DUMP_XML_CASELIST || runMode == RUNMODE_DUMP_TEXT_CASELIST) - { - const char* const ext = (runMode == RUNMODE_DUMP_XML_CASELIST) ? "xml" : "txt"; - const string fileName = string(packageName) + "-cases." + ext; - - print("Dumping all test case names in '%s' to file '%s'..\n", packageName, fileName.c_str()); - TCU_CHECK(m_testCaseListFile = fopen(fileName.c_str(), "wb")); - - if (runMode == RUNMODE_DUMP_XML_CASELIST) - { - TCU_CHECK(m_testCaseListWriter = qpXmlWriter_createFileWriter(m_testCaseListFile, DE_FALSE)); - - qpXmlWriter_startDocument(m_testCaseListWriter); - qpXmlWriter_startElement(m_testCaseListWriter, "TestCaseList", 0, DE_NULL); - } - } - - // Initialize package. - testPackage->init(); - - // Store test case wrapper - m_testCaseWrapper = &testPackage->getTestCaseWrapper(); - DE_ASSERT(m_testCaseWrapper); - - // Set archive. - m_testCtx.setCurrentArchive(testPackage->getArchive()); -} - -void TestExecutor::leaveTestPackage (TestPackage* testPackage) -{ - DE_ASSERT(testPackage); - - const RunMode runMode = m_cmdLine.getRunMode(); - if (runMode == RUNMODE_DUMP_XML_CASELIST) - { - qpXmlWriter_endElement(m_testCaseListWriter, "TestCaseList"); - qpXmlWriter_endDocument(m_testCaseListWriter); - qpXmlWriter_destroy(m_testCaseListWriter); - m_testCaseListWriter = DE_NULL; - } - - if (runMode == RUNMODE_DUMP_TEXT_CASELIST || runMode == RUNMODE_DUMP_XML_CASELIST) - { - fclose(m_testCaseListFile); - m_testCaseListFile = DE_NULL; - } - - DE_ASSERT(!m_testCaseListWriter && !m_testCaseListFile); - - m_testCaseWrapper = DE_NULL; - m_testCtx.setCurrentArchive(m_testCtx.getRootArchive()); - - // Deinitialize package. - testPackage->deinit(); -} - -void TestExecutor::enterGroupNode (TestCaseGroup* testGroup, const char* casePath) -{ - DE_UNREF(casePath); - testGroup->init(); -} - -void TestExecutor::leaveGroupNode (TestCaseGroup* testGroup) -{ - testGroup->deinit(); -} - -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(DE_FALSE); - return QP_TEST_CASE_TYPE_LAST; - } -} - -bool TestExecutor::enterTestCase (TestCase* testCase, const char* casePath) -{ - const RunMode runMode = m_cmdLine.getRunMode(); - const qpTestCaseType caseType = nodeTypeToTestCaseType(testCase->getNodeType()); - - if (runMode == RUNMODE_EXECUTE) - { - print("\nTest case '%s'..\n", casePath); - - m_testCtx.getLog().startCase(casePath, caseType); - m_isInTestCase = true; - m_testCtx.setTestResult(QP_TEST_RESULT_LAST, ""); - - if (!m_testCaseWrapper->initTestCase(testCase)) - { - if (m_testCtx.getTestResult() == QP_TEST_RESULT_LAST) - m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Unexpected error in subcase init"); - return false; - } - } - - return true; -} - -void TestExecutor::leaveTestCase (TestCase* testCase) -{ - const RunMode runMode = m_cmdLine.getRunMode(); - if (runMode == RUNMODE_EXECUTE) - { - // De-init case. - const bool deinitOk = m_testCaseWrapper->deinitTestCase(testCase); - const qpTestResult testResult = m_testCtx.getTestResult(); - const char* const testResultDesc = m_testCtx.getTestResultDesc(); - const bool terminateAfter = m_testCtx.getTerminateAfter(); - DE_ASSERT(testResult != QP_TEST_RESULT_LAST); - - m_isInTestCase = false; - m_testCtx.getLog().endCase(testResult, testResultDesc); - - // Update statistics. - print(" %s (%s)\n", qpGetTestResultName(testResult), testResultDesc); - - m_result.numExecuted += 1; - switch (testResult) - { - case QP_TEST_RESULT_PASS: m_result.numPassed += 1; break; - case QP_TEST_RESULT_NOT_SUPPORTED: m_result.numNotSupported += 1; break; - case QP_TEST_RESULT_QUALITY_WARNING: m_result.numWarnings += 1; break; - case QP_TEST_RESULT_COMPATIBILITY_WARNING: m_result.numWarnings += 1; break; - default: m_result.numFailed += 1; break; - } - - // terminateAfter, Resource error or any error in deinit means that execution should end - if (terminateAfter || !deinitOk || testResult == QP_TEST_RESULT_RESOURCE_ERROR) - m_abortSession = true; - - // \todo [2011-02-09 pyry] Disable watchdog temporarily? - if (m_testCtx.getWatchDog()) - qpWatchDog_reset(m_testCtx.getWatchDog()); - } -} - -// Return true while session should still continue, false otherwise. -bool TestExecutor::iterate (void) -{ - try - { - while (!m_sessionStack.empty()) - { - // Get full path to node. - string nodePath = ""; - for (int ndx = 0; ndx < (int)m_sessionStack.size(); ndx++) - { - NodeIter& iter = m_sessionStack[ndx]; - if (ndx > 1) // ignore root package - nodePath += "."; - nodePath += iter.node->getName(); - } - - // Handle the node. - NodeIter& iter = m_sessionStack[m_sessionStack.size()-1]; - DE_ASSERT(iter.node != DE_NULL); - TestNode* node = iter.node; - bool isLeaf = isTestNodeTypeExecutable(node->getNodeType()); - - switch (iter.getState()) - { - case NodeIter::STATE_BEGIN: - { - // Return to parent if name doesn't match filter. - if (!(isLeaf ? m_cmdLine.checkTestCaseName(nodePath.c_str()) : m_cmdLine.checkTestGroupName(nodePath.c_str()))) - { - m_sessionStack.pop_back(); - break; - } - - // Enter node. - bool enterOk = true; - switch (node->getNodeType()) - { - case NODETYPE_ROOT: /* nada */ break; - case NODETYPE_PACKAGE: enterTestPackage(static_cast(node), nodePath.c_str()); break; - case NODETYPE_GROUP: enterGroupNode(static_cast(node), nodePath.c_str()); break; - case NODETYPE_PERFORMANCE: - case NODETYPE_CAPABILITY: - case NODETYPE_ACCURACY: /* fall-trough */ - case NODETYPE_SELF_VALIDATE: enterOk = enterTestCase(static_cast(node), nodePath.c_str()); break; - default: DE_ASSERT(false); - } - - if (m_cmdLine.getRunMode() == RUNMODE_EXECUTE) - { - if (isLeaf) - { - if (enterOk) - iter.setState(NodeIter::STATE_EXECUTE_TEST); - else - iter.setState(NodeIter::STATE_FINISH); - } - else - { - iter.setState(NodeIter::STATE_TRAVERSE_CHILDREN); - } - } - else if (m_cmdLine.getRunMode() == RUNMODE_DUMP_XML_CASELIST) - { - if (node->getNodeType() != NODETYPE_ROOT && node->getNodeType() != NODETYPE_PACKAGE) - { - string caseName = iter.node->getName(); - string description = iter.node->getDescription(); - qpXmlAttribute attribs[8]; - int numAttribs = 0; - const char* caseType = DE_NULL; - - switch (node->getNodeType()) - { - case NODETYPE_SELF_VALIDATE: caseType = "SelfValidate"; break; - case NODETYPE_CAPABILITY: caseType = "Capability"; break; - case NODETYPE_ACCURACY: caseType = "Accuracy"; break; - case NODETYPE_PERFORMANCE: caseType = "Performance"; break; - default: caseType = "TestGroup"; break; - } - - attribs[numAttribs++] = qpSetStringAttrib("Name", caseName.c_str()); - attribs[numAttribs++] = qpSetStringAttrib("CaseType", caseType); - attribs[numAttribs++] = qpSetStringAttrib("Description", description.c_str()); - qpXmlWriter_startElement(m_testCaseListWriter, "TestCase", numAttribs, attribs); - } - - iter.setState(isLeaf ? NodeIter::STATE_FINISH : NodeIter::STATE_TRAVERSE_CHILDREN); - } - else if (m_cmdLine.getRunMode() == RUNMODE_DUMP_TEXT_CASELIST) - { - // \note Case list file is not open until we are in test package. - if (isLeaf) - fprintf(m_testCaseListFile, "TEST: %s\n", nodePath.c_str()); - else if (node->getNodeType() != NODETYPE_ROOT) - fprintf(m_testCaseListFile, "GROUP: %s\n", nodePath.c_str()); - iter.setState(isLeaf ? NodeIter::STATE_FINISH : NodeIter::STATE_TRAVERSE_CHILDREN); - } - - break; - } - - case NodeIter::STATE_EXECUTE_TEST: - { - // Touch the watchdog. - m_testCtx.touchWatchdog(); - - // Iterate the sub-case. - TestCase::IterateResult iterateResult = m_testCaseWrapper->iterateTestCase(static_cast(node)); - - if (iterateResult == TestCase::STOP) - iter.setState(NodeIter::STATE_FINISH); - - return true; // return after each iteration (when another iteration follows). - } - - case NodeIter::STATE_TRAVERSE_CHILDREN: - { - int numChildren = (int)iter.children.size(); - if (++iter.curChildNdx < numChildren) - { - // Push child to stack. - TestNode* childNode = iter.children[iter.curChildNdx]; - m_sessionStack.push_back(NodeIter(childNode)); - } - else - iter.setState(NodeIter::STATE_FINISH); - - break; - } - - case NodeIter::STATE_FINISH: - { - if (m_cmdLine.getRunMode() == RUNMODE_DUMP_XML_CASELIST) - { - if (node->getNodeType() != NODETYPE_ROOT && node->getNodeType() != NODETYPE_PACKAGE) - qpXmlWriter_endElement(m_testCaseListWriter, "TestCase"); - } - - // Leave node. - switch (node->getNodeType()) - { - case NODETYPE_ROOT: /* nada */ break; - case NODETYPE_PACKAGE: leaveTestPackage(static_cast(node)); break; - case NODETYPE_GROUP: leaveGroupNode(static_cast(node)); break; - case NODETYPE_ACCURACY: - case NODETYPE_CAPABILITY: - case NODETYPE_PERFORMANCE: /* fall-thru */ - case NODETYPE_SELF_VALIDATE: leaveTestCase(static_cast(node)); break; - default: DE_ASSERT(false); - } - - m_sessionStack.pop_back(); - - // Return if execution should abort. - if (m_abortSession) - return false; - - // Otherwise continue iterating. - break; - } - - default: - DE_ASSERT(DE_FALSE); - break; - } - } - } - catch (const std::exception& e) - { - print("TestExecutor::iterateSession(): Caught unhandled %s: %s\n", typeid(e).name(), e.what()); - throw; - } - - m_result.isComplete = true; - return false; -} - -} // tcu diff --git a/framework/common/tcuTestExecutor.hpp b/framework/common/tcuTestExecutor.hpp deleted file mode 100644 index 168c5c8..0000000 --- a/framework/common/tcuTestExecutor.hpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _TCUTESTEXECUTOR_HPP -#define _TCUTESTEXECUTOR_HPP -/*------------------------------------------------------------------------- - * 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 Base class for a test case. - *//*--------------------------------------------------------------------*/ - -#include "deDefs.h" -#include "tcuTestContext.hpp" -#include "tcuTestCase.hpp" -#include "tcuTestPackage.hpp" -#include "qpXmlWriter.h" - -#include - -namespace tcu -{ - -class CommandLine; - -//! Test run summary. -class TestRunResult -{ -public: - TestRunResult (void) { clear(); } - - void clear (void) - { - numExecuted = 0; - numPassed = 0; - numFailed = 0; - numNotSupported = 0; - numWarnings = 0; - isComplete = false; - } - - int numExecuted; //!< Total number of cases executed. - int numPassed; //!< Number of cases passed. - int numFailed; //!< Number of cases failed. - int numNotSupported; //!< Number of cases not supported. - int numWarnings; //!< Number of QualityWarning / CompatibilityWarning results. - bool isComplete; //!< Is run complete. -}; - -/*--------------------------------------------------------------------*//*! - * \brief Test executor - * - * Test executor traverses TestNode hierarchy and executes the cases - * included in current test case set. If no test case set is provided - * all test cases in hierarchy are executed. - *//*--------------------------------------------------------------------*/ -class TestExecutor -{ -public: - TestExecutor (TestContext& testCtx, const CommandLine& cmdLine); - ~TestExecutor (void); - - bool iterate (void); - - const TestRunResult& getResult (void) const { return m_result; } - - bool isInTestCase (void) const { return m_isInTestCase; } - -private: - struct NodeIter - { - enum State - { - STATE_BEGIN = 0, - STATE_TRAVERSE_CHILDREN, - STATE_EXECUTE_TEST, - STATE_FINISH, - - STATE_LAST - }; - - NodeIter (void) - : node (DE_NULL) - , curChildNdx (-1) - , m_state (STATE_LAST) - { - } - - NodeIter (TestNode* node_) - : node (node_) - , curChildNdx (-1) - , m_state (STATE_BEGIN) - { - } - - State getState (void) const - { - return m_state; - } - - void setState (State newState) - { - switch (newState) - { - case STATE_TRAVERSE_CHILDREN: - node->getChildren(children); - curChildNdx = -1; - break; - - default: - // nada - break; - } - - m_state = newState; - } - - TestNode* node; - std::vector children; - int curChildNdx; - - private: - State m_state; - }; - - TestExecutor (const TestExecutor&); // not allowed! - TestExecutor& operator= (const TestExecutor&); // not allowed! - - bool matchFolderName (const char* folderName) const; - bool matchCaseName (const char* caseName) const; - - void enterTestPackage (TestPackage* testPackage, const char* packageName); - void leaveTestPackage (TestPackage* testPackage); - - void enterGroupNode (TestCaseGroup* testGroup, const char* casePath); - void leaveGroupNode (TestCaseGroup* testGroup); - - bool enterTestCase (TestCase* testCase, const char* casePath); - void leaveTestCase (TestCase* testCase); - - // Member variables. - TestContext& m_testCtx; - const CommandLine& m_cmdLine; - TestPackageRoot* m_rootNode; - - TestCaseWrapper* m_testCaseWrapper; - - FILE* m_testCaseListFile; - qpXmlWriter* m_testCaseListWriter; - - // Current session state. - std::vector m_sessionStack; - bool m_abortSession; - bool m_isInTestCase; - - TestRunResult m_result; -}; - -} // tcu - -#endif // _TCUTESTEXECUTOR_HPP diff --git a/framework/common/tcuTestHierarchyIterator.cpp b/framework/common/tcuTestHierarchyIterator.cpp new file mode 100644 index 0000000..b0a6084 --- /dev/null +++ b/framework/common/tcuTestHierarchyIterator.cpp @@ -0,0 +1,259 @@ +/*------------------------------------------------------------------------- + * 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 Test case hierarchy iterator. + *//*--------------------------------------------------------------------*/ + +#include "tcuTestHierarchyIterator.hpp" +#include "tcuCommandLine.hpp" + +namespace tcu +{ + +using std::string; +using std::vector; + +// TestHierarchyInflater + +TestHierarchyInflater::TestHierarchyInflater (void) +{ +} + +TestHierarchyInflater::~TestHierarchyInflater (void) +{ +} + +// DefaultHierarchyInflater + +DefaultHierarchyInflater::DefaultHierarchyInflater (TestContext& testCtx) + : m_testCtx(testCtx) +{ +} + +DefaultHierarchyInflater::~DefaultHierarchyInflater (void) +{ +} + +void DefaultHierarchyInflater::enterTestPackage (TestPackage* testPackage, vector& children) +{ + { + Archive* const pkgArchive = testPackage->getArchive(); + + if (pkgArchive) + m_testCtx.setCurrentArchive(*pkgArchive); + else + m_testCtx.setCurrentArchive(m_testCtx.getRootArchive()); + } + + testPackage->init(); + testPackage->getChildren(children); +} + +void DefaultHierarchyInflater::leaveTestPackage (TestPackage* testPackage) +{ + m_testCtx.setCurrentArchive(m_testCtx.getRootArchive()); + testPackage->deinit(); +} + +void DefaultHierarchyInflater::enterGroupNode (TestCaseGroup* testGroup, vector& children) +{ + testGroup->init(); + testGroup->getChildren(children); +} + +void DefaultHierarchyInflater::leaveGroupNode (TestCaseGroup* testGroup) +{ + testGroup->deinit(); +} + +// TestHierarchyIterator + +TestHierarchyIterator::TestHierarchyIterator (TestPackageRoot& rootNode, + TestHierarchyInflater& inflater, + const CommandLine& cmdLine) + : m_inflater (inflater) + , m_cmdLine (cmdLine) +{ + // Init traverse state and "seek" to first reportable node. + NodeIter iter(&rootNode); + iter.setState(NodeIter::STATE_ENTER); // Root is never reported + m_sessionStack.push_back(iter); + next(); +} + +TestHierarchyIterator::~TestHierarchyIterator (void) +{ + // Tear down inflated nodes in m_sessionStack + for (vector::reverse_iterator iter = m_sessionStack.rbegin(); iter != m_sessionStack.rend(); ++iter) + { + TestNode* const node = iter->node; + const TestNodeType nodeType = node->getNodeType(); + + switch (nodeType) + { + case NODETYPE_ROOT: /* root is not de-initialized */ break; + case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast(node)); break; + case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast(node)); break; + default: + break; + } + } +} + +TestHierarchyIterator::State TestHierarchyIterator::getState (void) const +{ + if (!m_sessionStack.empty()) + { + const NodeIter& iter = m_sessionStack.back(); + + DE_ASSERT(iter.getState() == NodeIter::STATE_ENTER || + iter.getState() == NodeIter::STATE_LEAVE); + + return iter.getState() == NodeIter::STATE_ENTER ? STATE_ENTER_NODE : STATE_LEAVE_NODE; + } + else + return STATE_FINISHED; +} + +TestNode* TestHierarchyIterator::getNode (void) const +{ + DE_ASSERT(getState() != STATE_FINISHED); + return m_sessionStack.back().node; +} + +const std::string& TestHierarchyIterator::getNodePath (void) const +{ + DE_ASSERT(getState() != STATE_FINISHED); + return m_nodePath; +} + +std::string TestHierarchyIterator::buildNodePath (const vector& nodeStack) +{ + string nodePath; + for (size_t ndx = 1; ndx < nodeStack.size(); ndx++) + { + const NodeIter& iter = nodeStack[ndx]; + if (ndx > 1) // ignore root package + nodePath += "."; + nodePath += iter.node->getName(); + } + return nodePath; +} + +void TestHierarchyIterator::next (void) +{ + while (!m_sessionStack.empty()) + { + NodeIter& iter = m_sessionStack.back(); + TestNode* const node = iter.node; + const bool isLeaf = isTestNodeTypeExecutable(node->getNodeType()); + + switch (iter.getState()) + { + case NodeIter::STATE_INIT: + { + const std::string nodePath = buildNodePath(m_sessionStack); + + // Return to parent if name doesn't match filter. + if (!(isLeaf ? m_cmdLine.checkTestCaseName(nodePath.c_str()) : m_cmdLine.checkTestGroupName(nodePath.c_str()))) + { + m_sessionStack.pop_back(); + break; + } + + m_nodePath = nodePath; + iter.setState(NodeIter::STATE_ENTER); + return; // Yield enter event + } + + case NodeIter::STATE_ENTER: + { + if (isLeaf) + { + iter.setState(NodeIter::STATE_LEAVE); + return; // Yield leave event + } + else + { + iter.setState(NodeIter::STATE_TRAVERSE_CHILDREN); + iter.children.clear(); + + switch (node->getNodeType()) + { + case NODETYPE_ROOT: static_cast(node)->getChildren(iter.children); break; + case NODETYPE_PACKAGE: m_inflater.enterTestPackage(static_cast(node), iter.children); break; + case NODETYPE_GROUP: m_inflater.enterGroupNode(static_cast(node), iter.children); break; + default: + DE_ASSERT(false); + } + } + + break; + } + + case NodeIter::STATE_TRAVERSE_CHILDREN: + { + int numChildren = (int)iter.children.size(); + if (++iter.curChildNdx < numChildren) + { + // Push child to stack. + TestNode* childNode = iter.children[iter.curChildNdx]; + m_sessionStack.push_back(NodeIter(childNode)); + } + else + { + iter.setState(NodeIter::STATE_LEAVE); + if (node->getNodeType() != NODETYPE_ROOT) + return; // Yield leave event + } + + break; + } + + case NodeIter::STATE_LEAVE: + { + // Leave node. + if (!isLeaf) + { + switch (node->getNodeType()) + { + case NODETYPE_ROOT: /* root is not de-initialized */ break; + case NODETYPE_PACKAGE: m_inflater.leaveTestPackage(static_cast(node)); break; + case NODETYPE_GROUP: m_inflater.leaveGroupNode(static_cast(node)); break; + default: + DE_ASSERT(false); + } + } + + m_sessionStack.pop_back(); + m_nodePath = buildNodePath(m_sessionStack); + break; + } + + default: + DE_ASSERT(false); + return; + } + } + + DE_ASSERT(m_sessionStack.empty() && getState() == STATE_FINISHED); +} + +} // tcu diff --git a/framework/common/tcuTestHierarchyIterator.hpp b/framework/common/tcuTestHierarchyIterator.hpp new file mode 100644 index 0000000..ea4a4ea --- /dev/null +++ b/framework/common/tcuTestHierarchyIterator.hpp @@ -0,0 +1,202 @@ +#ifndef _TCUTESTHIERARCHYITERATOR_HPP +#define _TCUTESTHIERARCHYITERATOR_HPP +/*------------------------------------------------------------------------- + * 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 Test case hierarchy iterator. + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestContext.hpp" +#include "tcuTestCase.hpp" +#include "tcuTestPackage.hpp" + +#include + +namespace tcu +{ + +class CommandLine; + +/*--------------------------------------------------------------------*//*! + * \brief Test hierarchy inflater + * + * This interface is used by TestHierarchyIterator to materialize, and clean + * up, test hierarchy on-demand while walking through it. + *//*--------------------------------------------------------------------*/ +class TestHierarchyInflater +{ +public: + TestHierarchyInflater (void); + + virtual void enterTestPackage (TestPackage* testPackage, std::vector& children) = 0; + virtual void leaveTestPackage (TestPackage* testPackage) = 0; + + virtual void enterGroupNode (TestCaseGroup* testGroup, std::vector& children) = 0; + virtual void leaveGroupNode (TestCaseGroup* testGroup) = 0; + +protected: + ~TestHierarchyInflater (void); +}; + +// \todo [2015-02-26 pyry] Hierarchy traversal should not depend on TestContext +class DefaultHierarchyInflater : public TestHierarchyInflater +{ +public: + DefaultHierarchyInflater (TestContext& testCtx); + ~DefaultHierarchyInflater (void); + + virtual void enterTestPackage (TestPackage* testPackage, std::vector& children); + virtual void leaveTestPackage (TestPackage* testPackage); + + virtual void enterGroupNode (TestCaseGroup* testGroup, std::vector& children); + virtual void leaveGroupNode (TestCaseGroup* testGroup); + +protected: + TestContext& m_testCtx; +}; + +/*--------------------------------------------------------------------*//*! + * \brief Test hierarchy iterator + * + * Test hierarchy iterator allows walking test case hierarchy in depth-first + * order. The walked sub-tree is limited by command line parameters. + * + * Iterator signals current state with getState(), which initally, and after + * each increment (next()) may report one of the following: + * + * STATE_ENTER_NODE: A test node has been entered to for the first time. + * Node can be queried with getNode() and its full path with getNodePath(). + * For group nodes the iterator will next enter first matching child node. + * For executable (test case) nodes STATE_LEAVE_NODE will always be reported + * immediately after entering that node. + * + * STATE_LEAVE_NODE: Iterator is leaving a node. In case of group nodes this + * means that all child nodes and their children have been processed. For + * executable nodes the iterator will either move on to the next sibling, + * or leave the parent group if the reported node was last child of that + * group. + * + * Root node is never reported, but instead iteration will start on first + * matching test package node, if there is any. + * + * Test hierarchy is created on demand with help of TestHierarchyInflater. + * Upon entering a group node, after STATE_ENTER_NODE has been signaled, + * inflater is called to construct the list of child nodes for that group. + * Upon exiting a group node, before STATE_LEAVE_NODE is called, inflater + * is asked to clean up any resources by calling leaveGroupNode() or + * leaveTestPackage() depending on the type of the node. + *//*--------------------------------------------------------------------*/ +class TestHierarchyIterator +{ +public: + TestHierarchyIterator (TestPackageRoot& rootNode, TestHierarchyInflater& inflater, const CommandLine& cmdLine); + ~TestHierarchyIterator (void); + + enum State + { + STATE_ENTER_NODE = 0, + STATE_LEAVE_NODE, + STATE_FINISHED, + + STATE_LAST + }; + + State getState (void) const; + + TestNode* getNode (void) const; + const std::string& getNodePath (void) const; + + void next (void); + +private: + struct NodeIter + { + enum State + { + STATE_INIT = 0, + STATE_ENTER, + STATE_TRAVERSE_CHILDREN, + STATE_LEAVE, + + STATE_LAST + }; + + NodeIter (void) + : node (DE_NULL) + , curChildNdx (-1) + , m_state (STATE_LAST) + { + } + + NodeIter (TestNode* node_) + : node (node_) + , curChildNdx (-1) + , m_state (STATE_INIT) + { + } + + State getState (void) const + { + return m_state; + } + + void setState (State newState) + { + switch (newState) + { + case STATE_TRAVERSE_CHILDREN: + curChildNdx = -1; + break; + + default: + break; + } + + m_state = newState; + } + + TestNode* node; + std::vector children; + int curChildNdx; + + private: + State m_state; + }; + + TestHierarchyIterator (const TestHierarchyIterator&); // not allowed! + TestHierarchyIterator& operator= (const TestHierarchyIterator&); // not allowed! + + bool matchFolderName (const std::string& folderName) const; + bool matchCaseName (const std::string& caseName) const; + + static std::string buildNodePath (const std::vector& nodeStack); + + TestHierarchyInflater& m_inflater; + const CommandLine& m_cmdLine; + + // Current session state. + std::vector m_sessionStack; + std::string m_nodePath; +}; + +} // tcu + +#endif // _TCUTESTHIERARCHYITERATOR_HPP diff --git a/framework/common/tcuTestHierarchyUtil.cpp b/framework/common/tcuTestHierarchyUtil.cpp new file mode 100644 index 0000000..e8cd6c9 --- /dev/null +++ b/framework/common/tcuTestHierarchyUtil.cpp @@ -0,0 +1,196 @@ +/*------------------------------------------------------------------------- + * 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 Test hierarchy utilities. + *//*--------------------------------------------------------------------*/ + +#include "tcuTestHierarchyUtil.hpp" +#include "tcuStringTemplate.hpp" +#include "qpXmlWriter.h" + +#include + +namespace tcu +{ + +using std::string; + +static const char* getNodeTypeName (TestNodeType nodeType) +{ + switch (nodeType) + { + case NODETYPE_SELF_VALIDATE: return "SelfValidate"; + case NODETYPE_CAPABILITY: return "Capability"; + case NODETYPE_ACCURACY: return "Accuracy"; + case NODETYPE_PERFORMANCE: return "Performance"; + case NODETYPE_GROUP: return "TestGroup"; + default: + DE_ASSERT(false); + return DE_NULL; + } +} + +// Utilities + +static std::string makePackageFilename (const std::string& pattern, const std::string& packageName, const std::string& typeExtension) +{ + std::map args; + args["packageName"] = packageName; + args["typeExtension"] = typeExtension; + return StringTemplate(pattern).specialize(args); +} + +void writeXmlCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine) +{ + const char* const filenamePattern = "${packageName}-cases.${typeExtension}"; // \todo [2015-02-27 pyry] Make this command line argument + DefaultHierarchyInflater inflater (testCtx); + TestHierarchyIterator iter (root, inflater, cmdLine); + FILE* curFile = DE_NULL; + qpXmlWriter* writer = DE_NULL; + + try + { + while (iter.getState() != TestHierarchyIterator::STATE_FINISHED) + { + const TestNode* const node = iter.getNode(); + const TestNodeType nodeType = node->getNodeType(); + const bool isEnter = iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE; + + DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE || + iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE); + + if (nodeType == NODETYPE_PACKAGE) + { + if (isEnter) + { + const string filename = makePackageFilename(filenamePattern, node->getName(), "xml"); + qpXmlAttribute attribs[2]; + int numAttribs = 0; + + DE_ASSERT(!curFile && !writer); + + print("Writing test cases from '%s' to file '%s'..\n", node->getName(), filename.c_str()); + + curFile = fopen(filename.c_str(), "wb"); + if (!curFile) + throw Exception("Failed to open " + filename); + + writer = qpXmlWriter_createFileWriter(curFile, DE_FALSE); + if (!writer) + throw Exception("Failed to create qpXmlWriter"); + + attribs[numAttribs++] = qpSetStringAttrib("PackageName", node->getName()); + attribs[numAttribs++] = qpSetStringAttrib("Description", node->getDescription()); + DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs)); + + if (!qpXmlWriter_startDocument(writer) || + !qpXmlWriter_startElement(writer, "TestCaseList", numAttribs, attribs)) + throw Exception("Failed to start XML document"); + } + else + { + if (!qpXmlWriter_endElement(writer, "TestCaseList") || + !qpXmlWriter_endDocument(writer)) + throw Exception("Failed to terminate XML document"); + + qpXmlWriter_destroy(writer); + fclose(curFile); + + writer = DE_NULL; + curFile = DE_NULL; + } + } + else + { + if (isEnter) + { + const string caseName = node->getName(); + const string description = node->getDescription(); + qpXmlAttribute attribs[3]; + int numAttribs = 0; + + attribs[numAttribs++] = qpSetStringAttrib("Name", caseName.c_str()); + attribs[numAttribs++] = qpSetStringAttrib("CaseType", getNodeTypeName(nodeType)); + attribs[numAttribs++] = qpSetStringAttrib("Description", description.c_str()); + DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs)); + + if (!qpXmlWriter_startElement(writer, "TestCase", numAttribs, attribs)) + throw Exception("Writing to case list file failed"); + } + else + { + if (!qpXmlWriter_endElement(writer, "TestCase")) + throw tcu::Exception("Writing to case list file failed"); + } + } + + iter.next(); + } + } + catch (...) + { + if (writer) + qpXmlWriter_destroy(writer); + + if (curFile) + fclose(curFile); + + throw; + } + + DE_ASSERT(!curFile && !writer); +} + +void writeTxtCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine) +{ + const char* const filenamePattern = "${packageName}-cases.${typeExtension}"; // \todo [2015-02-27 pyry] Make this command line argument + DefaultHierarchyInflater inflater (testCtx); + TestHierarchyIterator iter (root, inflater, cmdLine); + + while (iter.getState() != TestHierarchyIterator::STATE_FINISHED) + { + DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE && + iter.getNode()->getNodeType() == NODETYPE_PACKAGE); + + const char* pkgName = iter.getNode()->getName(); + const string filename = makePackageFilename(filenamePattern, pkgName, "txt"); + std::ofstream out (filename.c_str(), std::ios_base::binary); + + if (!out.is_open() || !out.good()) + throw Exception("Failed to open " + filename); + + print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str()); + + iter.next(); + + while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE) + { + if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE) + out << (isTestNodeTypeExecutable(iter.getNode()->getNodeType()) ? "TEST" : "GROUP") << ": " << iter.getNodePath() << "\n"; + iter.next(); + } + + DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE && + iter.getNode()->getNodeType() == NODETYPE_PACKAGE); + iter.next(); + } +} + +} // tcu diff --git a/framework/common/tcuTestCaseWrapper.hpp b/framework/common/tcuTestHierarchyUtil.hpp similarity index 59% rename from framework/common/tcuTestCaseWrapper.hpp rename to framework/common/tcuTestHierarchyUtil.hpp index 65bf406..683f7f1 100644 --- a/framework/common/tcuTestCaseWrapper.hpp +++ b/framework/common/tcuTestHierarchyUtil.hpp @@ -1,5 +1,5 @@ -#ifndef _TCUTESTCASEWRAPPER_HPP -#define _TCUTESTCASEWRAPPER_HPP +#ifndef _TCUTESTHIERARCHYUTIL_HPP +#define _TCUTESTHIERARCHYUTIL_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- @@ -20,33 +20,19 @@ * *//*! * \file - * \brief Test case wrapper for test execution. + * \brief Test hierarchy utilities. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" -#include "tcuTestContext.hpp" -#include "tcuTestCase.hpp" +#include "tcuTestHierarchyIterator.hpp" namespace tcu { -class TestCaseWrapper -{ -public: - TestCaseWrapper (TestContext& testCtx); - virtual ~TestCaseWrapper (void); - - virtual bool initTestCase (TestCase* testCase); - virtual bool deinitTestCase (TestCase* testCase); - - virtual TestNode::IterateResult iterateTestCase (TestCase* testCase); - -protected: - TestContext& m_testCtx; - - deUint64 m_testStartTime; //!< For logging test case durations. -}; +// \todo [2015-02-26 pyry] Remove TestContext requirement +void writeXmlCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine); +void writeTxtCaselists (TestPackageRoot& root, TestContext& testCtx, const tcu::CommandLine& cmdLine); } // tcu -#endif // _TCUTESTCASEWRAPPER_HPP +#endif // _TCUTESTHIERARCHYUTIL_HPP diff --git a/framework/common/tcuTestPackage.cpp b/framework/common/tcuTestPackage.cpp index 8ab2580..047acc9 100644 --- a/framework/common/tcuTestPackage.cpp +++ b/framework/common/tcuTestPackage.cpp @@ -144,6 +144,15 @@ TestPackageRoot::TestPackageRoot (TestContext& testCtx, const vector& { } +TestPackageRoot::TestPackageRoot (TestContext& testCtx, const TestPackageRegistry* packageRegistry) + : TestNode(testCtx, NODETYPE_ROOT, "", "") +{ + const vector& packageInfos = packageRegistry->getPackageInfos(); + + for (int i = 0; i < (int)packageInfos.size(); i++) + addChild(packageInfos[i]->createFunc(testCtx)); +} + TestPackageRoot::~TestPackageRoot (void) { } diff --git a/framework/common/tcuTestPackage.hpp b/framework/common/tcuTestPackage.hpp index 2956316..2e7aa74 100644 --- a/framework/common/tcuTestPackage.hpp +++ b/framework/common/tcuTestPackage.hpp @@ -25,31 +25,59 @@ #include "tcuDefs.hpp" #include "tcuTestCase.hpp" -#include "tcuTestCaseWrapper.hpp" namespace tcu { /*--------------------------------------------------------------------*//*! - * \brief Base class for test packages. - * - * Test packages are root-level test groups. Test case exposes couple of - * extra customization points. Test package can define custom TestCaseWrapper - * and archive (usually ResourcePrefix around default archive) for resources. + * \brief Test case execution interface. * - * Test package is typically responsible of setting up rendering context + * TestCaseExecutor provides package-specific resources & initialization * for test cases. + * + * \todo [2015-03-18 pyry] Replace with following API: + * + * class TestInstance + * { + * public: + * TestInstance (TestContext& testCtx); + * tcu::TestResult iterate (void); + * }; + * + * class TestInstanceFactory (???) + * { + * public: + * TestInstance* createInstance (const TestCase* testCase, const std::string& path); + * }; + *//*--------------------------------------------------------------------*/ +class TestCaseExecutor +{ +public: + virtual ~TestCaseExecutor (void) {} + + virtual void init (TestCase* testCase, const std::string& path) = 0; + virtual void deinit (TestCase* testCase) = 0; + virtual TestNode::IterateResult iterate (TestCase* testCase) = 0; +}; + +/*--------------------------------------------------------------------*//*! + * \brief Base class for test packages. + * + * Test packages are root-level test groups. They also provide package- + * specific test case executor, see TestCaseExecutor. *//*--------------------------------------------------------------------*/ class TestPackage : public TestNode { public: - TestPackage (TestContext& testCtx, const char* name, const char* description); - virtual ~TestPackage (void); + TestPackage (TestContext& testCtx, const char* name, const char* description); + virtual ~TestPackage (void); + + virtual TestCaseExecutor* createExecutor (void) const = 0; - virtual IterateResult iterate (void); + // Deprecated + virtual Archive* getArchive (void) { return DE_NULL; } - virtual TestCaseWrapper& getTestCaseWrapper (void) = DE_NULL; - virtual Archive& getArchive (void) = DE_NULL; + virtual IterateResult iterate (void); }; // TestPackageRegistry @@ -101,6 +129,7 @@ class TestPackageRoot : public TestNode public: TestPackageRoot (TestContext& testCtx); TestPackageRoot (TestContext& testCtx, const std::vector& children); + TestPackageRoot (TestContext& testCtx, const TestPackageRegistry* packageRegistry); virtual ~TestPackageRoot (void); virtual IterateResult iterate (void); diff --git a/framework/common/tcuTestSessionExecutor.cpp b/framework/common/tcuTestSessionExecutor.cpp new file mode 100644 index 0000000..630f22c --- /dev/null +++ b/framework/common/tcuTestSessionExecutor.cpp @@ -0,0 +1,292 @@ +/*------------------------------------------------------------------------- + * 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 Test executor. + *//*--------------------------------------------------------------------*/ + +#include "tcuTestSessionExecutor.hpp" +#include "tcuTestLog.hpp" + +#include "deClock.h" + +namespace tcu +{ + +using std::vector; + +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; + } +} + +TestSessionExecutor::TestSessionExecutor (TestPackageRoot& root, TestContext& testCtx) + : m_testCtx (testCtx) + , m_inflater (testCtx) + , m_iterator (root, m_inflater, testCtx.getCommandLine()) + , m_state (STATE_TRAVERSE_HIERARCHY) + , m_abortSession (false) + , m_isInTestCase (false) + , m_testStartTime (0) +{ +} + +TestSessionExecutor::~TestSessionExecutor (void) +{ +} + +bool TestSessionExecutor::iterate (void) +{ + for (;;) + { + switch (m_state) + { + case STATE_TRAVERSE_HIERARCHY: + { + const TestHierarchyIterator::State hierIterState = m_iterator.getState(); + + if (hierIterState == TestHierarchyIterator::STATE_ENTER_NODE || + hierIterState == TestHierarchyIterator::STATE_LEAVE_NODE) + { + TestNode* const curNode = m_iterator.getNode(); + const TestNodeType nodeType = curNode->getNodeType(); + const bool isEnter = hierIterState == TestHierarchyIterator::STATE_ENTER_NODE; + + switch (nodeType) + { + case NODETYPE_PACKAGE: + { + TestPackage* const testPackage = static_cast(curNode); + isEnter ? enterTestPackage(testPackage) : leaveTestPackage(testPackage); + break; + } + + case NODETYPE_GROUP: + break; // nada + + case NODETYPE_SELF_VALIDATE: + case NODETYPE_PERFORMANCE: + case NODETYPE_CAPABILITY: + case NODETYPE_ACCURACY: + { + TestCase* const testCase = static_cast(curNode); + + if (isEnter) + { + if (enterTestCase(testCase, m_iterator.getNodePath())) + m_state = STATE_EXECUTE_TEST_CASE; + // else remain in TRAVERSING_HIERARCHY => node will be exited from in the next iteration + } + else + leaveTestCase(testCase); + + break; + } + + default: + DE_ASSERT(false); + break; + } + + m_iterator.next(); + break; + } + else + { + DE_ASSERT(hierIterState == TestHierarchyIterator::STATE_FINISHED); + return false; + } + } + + case STATE_EXECUTE_TEST_CASE: + { + DE_ASSERT(m_iterator.getState() == TestHierarchyIterator::STATE_LEAVE_NODE && + isTestNodeTypeExecutable(m_iterator.getNode()->getNodeType())); + + TestCase* const testCase = static_cast(m_iterator.getNode()); + const TestCase::IterateResult iterResult = iterateTestCase(testCase); + + if (iterResult == TestCase::STOP) + m_state = STATE_TRAVERSE_HIERARCHY; + + return true; + } + + default: + DE_ASSERT(false); + break; + } + } + + DE_ASSERT(false); + return false; +} + +void TestSessionExecutor::enterTestPackage (TestPackage* testPackage) +{ + // Create test case wrapper + DE_ASSERT(!m_caseExecutor); + m_caseExecutor = de::MovePtr(testPackage->createExecutor()); +} + +void TestSessionExecutor::leaveTestPackage (TestPackage* testPackage) +{ + DE_UNREF(testPackage); + m_caseExecutor.clear(); +} + +bool TestSessionExecutor::enterTestCase (TestCase* testCase, const std::string& casePath) +{ + TestLog& log = m_testCtx.getLog(); + const qpTestCaseType caseType = nodeTypeToTestCaseType(testCase->getNodeType()); + bool initOk = false; + + print("\nTest case '%s'..\n", casePath.c_str()); + + m_testCtx.setTestResult(QP_TEST_RESULT_LAST, ""); + m_testCtx.setTerminateAfter(false); + log.startCase(casePath.c_str(), caseType); + + m_isInTestCase = true; + m_testStartTime = deGetMicroseconds(); + + try + { + m_caseExecutor->init(testCase, casePath); + initOk = true; + } + catch (const std::bad_alloc&) + { + DE_ASSERT(!initOk); + m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Failed to allocate memory in test case init"); + m_testCtx.setTerminateAfter(true); + } + catch (const tcu::TestException& e) + { + DE_ASSERT(!initOk); + DE_ASSERT(e.getTestResult() != QP_TEST_RESULT_LAST); + m_testCtx.setTestResult(e.getTestResult(), e.getMessage()); + m_testCtx.setTerminateAfter(e.isFatal()); + log << e; + } + catch (const tcu::Exception& e) + { + DE_ASSERT(!initOk); + m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage()); + log << e; + } + + DE_ASSERT(initOk || m_testCtx.getTestResult() != QP_TEST_RESULT_LAST); + + return initOk; +} + +void TestSessionExecutor::leaveTestCase (TestCase* testCase) +{ + TestLog& log = m_testCtx.getLog(); + + // De-init case. + 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); + } + + { + const deInt64 duration = deGetMicroseconds()-m_testStartTime; + m_testStartTime = 0; + m_testCtx.getLog() << TestLog::Integer("TestDuration", "Test case duration in microseconds", "us", QP_KEY_TAG_TIME, duration); + } + + { + const qpTestResult testResult = m_testCtx.getTestResult(); + const char* const testResultDesc = m_testCtx.getTestResultDesc(); + const bool terminateAfter = m_testCtx.getTerminateAfter(); + DE_ASSERT(testResult != QP_TEST_RESULT_LAST); + + m_isInTestCase = false; + m_testCtx.getLog().endCase(testResult, testResultDesc); + + // Update statistics. + print(" %s (%s)\n", qpGetTestResultName(testResult), testResultDesc); + + m_status.numExecuted += 1; + switch (testResult) + { + case QP_TEST_RESULT_PASS: m_status.numPassed += 1; break; + case QP_TEST_RESULT_NOT_SUPPORTED: m_status.numNotSupported += 1; break; + case QP_TEST_RESULT_QUALITY_WARNING: m_status.numWarnings += 1; break; + case QP_TEST_RESULT_COMPATIBILITY_WARNING: m_status.numWarnings += 1; break; + default: m_status.numFailed += 1; break; + } + + // terminateAfter, Resource error or any error in deinit means that execution should end + if (terminateAfter || testResult == QP_TEST_RESULT_RESOURCE_ERROR) + m_abortSession = true; + } + + if (m_testCtx.getWatchDog()) + qpWatchDog_reset(m_testCtx.getWatchDog()); +} + +TestCase::IterateResult TestSessionExecutor::iterateTestCase (TestCase* testCase) +{ + TestLog& log = m_testCtx.getLog(); + 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"); + m_testCtx.setTerminateAfter(true); + } + catch (const tcu::TestException& e) + { + log << e; + m_testCtx.setTestResult(e.getTestResult(), e.getMessage()); + m_testCtx.setTerminateAfter(e.isFatal()); + } + catch (const tcu::Exception& e) + { + log << e; + m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage()); + } + + return iterateResult; +} + +} // tcu diff --git a/framework/common/tcuTestSessionExecutor.hpp b/framework/common/tcuTestSessionExecutor.hpp new file mode 100644 index 0000000..ba5172f --- /dev/null +++ b/framework/common/tcuTestSessionExecutor.hpp @@ -0,0 +1,102 @@ +#ifndef _TCUTESTSESSIONEXECUTOR_HPP +#define _TCUTESTSESSIONEXECUTOR_HPP +/*------------------------------------------------------------------------- + * 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 Test executor. + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestContext.hpp" +#include "tcuTestCase.hpp" +#include "tcuTestPackage.hpp" +#include "tcuTestHierarchyIterator.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ + +//! Test run summary. +class TestRunStatus +{ +public: + TestRunStatus (void) { clear(); } + + void clear (void) + { + numExecuted = 0; + numPassed = 0; + numFailed = 0; + numNotSupported = 0; + numWarnings = 0; + isComplete = false; + } + + int numExecuted; //!< Total number of cases executed. + int numPassed; //!< Number of cases passed. + int numFailed; //!< Number of cases failed. + int numNotSupported; //!< Number of cases not supported. + int numWarnings; //!< Number of QualityWarning / CompatibilityWarning results. + bool isComplete; //!< Is run complete. +}; + +class TestSessionExecutor +{ +public: + TestSessionExecutor (TestPackageRoot& root, TestContext& testCtx); + ~TestSessionExecutor(void); + + bool iterate (void); + + bool isInTestCase (void) const { return m_isInTestCase; } + const TestRunStatus& getStatus (void) const { return m_status; } + +private: + void enterTestPackage (TestPackage* testPackage); + void leaveTestPackage (TestPackage* testPackage); + + bool enterTestCase (TestCase* testCase, const std::string& casePath); + TestCase::IterateResult iterateTestCase (TestCase* testCase); + void leaveTestCase (TestCase* testCase); + + enum State + { + STATE_TRAVERSE_HIERARCHY = 0, + STATE_EXECUTE_TEST_CASE, + + STATE_LAST + }; + + TestContext& m_testCtx; + + DefaultHierarchyInflater m_inflater; + TestHierarchyIterator m_iterator; + + de::MovePtr m_caseExecutor; + TestRunStatus m_status; + State m_state; + bool m_abortSession; + bool m_isInTestCase; + deUint64 m_testStartTime; +}; + +} // tcu + +#endif // _TCUTESTSESSIONEXECUTOR_HPP diff --git a/modules/egl/teglTestPackage.cpp b/modules/egl/teglTestPackage.cpp index 1602778..1336e14 100644 --- a/modules/egl/teglTestPackage.cpp +++ b/modules/egl/teglTestPackage.cpp @@ -127,29 +127,32 @@ public: } }; -TestCaseWrapper::TestCaseWrapper (EglTestContext& eglTestCtx) - : tcu::TestCaseWrapper(eglTestCtx.getTestContext()) +class TestCaseWrapper : public tcu::TestCaseExecutor { -} +public: + TestCaseWrapper (void) + { + } -TestCaseWrapper::~TestCaseWrapper (void) -{ -} + ~TestCaseWrapper (void) + { + } -bool TestCaseWrapper::initTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::initTestCase(testCase); -} + void init (tcu::TestCase* testCase, const std::string&) + { + testCase->init(); + } -bool TestCaseWrapper::deinitTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::deinitTestCase(testCase); -} + void deinit (tcu::TestCase* testCase) + { + testCase->deinit(); + } -tcu::TestNode::IterateResult TestCaseWrapper::iterateTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::iterateTestCase(testCase); -} + tcu::TestNode::IterateResult iterate (tcu::TestCase* testCase) + { + return testCase->iterate(); + } +}; static const eglu::NativeDisplayFactory& getDefaultDisplayFactory (tcu::TestContext& testCtx) { @@ -158,20 +161,9 @@ static const eglu::NativeDisplayFactory& getDefaultDisplayFactory (tcu::TestCont return factory; } -PackageContext::PackageContext (tcu::TestContext& testCtx) - : m_eglTestCtx (testCtx, getDefaultDisplayFactory(testCtx)) - , m_caseWrapper (m_eglTestCtx) -{ -} - -PackageContext::~PackageContext (void) -{ -} - TestPackage::TestPackage (tcu::TestContext& testCtx) : tcu::TestPackage (testCtx, "dEQP-EGL", "dEQP EGL Tests") - , m_packageCtx (DE_NULL) - , m_archive (testCtx.getRootArchive(), "egl/") + , m_eglTestCtx (DE_NULL) { } @@ -179,25 +171,25 @@ TestPackage::~TestPackage (void) { // Destroy children first since destructors may access context. TestNode::deinit(); - delete m_packageCtx; + delete m_eglTestCtx; } void TestPackage::init (void) { - DE_ASSERT(!m_packageCtx); - m_packageCtx = new PackageContext(m_testCtx); + DE_ASSERT(!m_eglTestCtx); + m_eglTestCtx = new EglTestContext(m_testCtx, getDefaultDisplayFactory(m_testCtx)); try { - addChild(new InfoTests (m_packageCtx->getEglTestContext())); - addChild(new FunctionalTests (m_packageCtx->getEglTestContext())); - addChild(new PerformanceTests (m_packageCtx->getEglTestContext())); - addChild(new StressTests (m_packageCtx->getEglTestContext())); + addChild(new InfoTests (*m_eglTestCtx)); + addChild(new FunctionalTests (*m_eglTestCtx)); + addChild(new PerformanceTests (*m_eglTestCtx)); + addChild(new StressTests (*m_eglTestCtx)); } catch (...) { - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_eglTestCtx; + m_eglTestCtx = DE_NULL; throw; } @@ -206,8 +198,13 @@ void TestPackage::init (void) void TestPackage::deinit (void) { tcu::TestNode::deinit(); - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_eglTestCtx; + m_eglTestCtx = DE_NULL; +} + +tcu::TestCaseExecutor* TestPackage::createExecutor (void) const +{ + return new TestCaseWrapper(); } } // egl diff --git a/modules/egl/teglTestPackage.hpp b/modules/egl/teglTestPackage.hpp index a6b1073..c9f0db2 100644 --- a/modules/egl/teglTestPackage.hpp +++ b/modules/egl/teglTestPackage.hpp @@ -26,39 +26,12 @@ #include "tcuDefs.hpp" #include "tcuTestPackage.hpp" #include "teglTestCase.hpp" -#include "tcuResource.hpp" namespace deqp { namespace egl { -class TestCaseWrapper : public tcu::TestCaseWrapper -{ -public: - TestCaseWrapper (EglTestContext& eglTestContext); - ~TestCaseWrapper (void); - - bool initTestCase (tcu::TestCase* testCase); - bool deinitTestCase (tcu::TestCase* testCase); - - tcu::TestNode::IterateResult iterateTestCase (tcu::TestCase* testCase); -}; - -class PackageContext -{ -public: - PackageContext (tcu::TestContext& testCtx); - ~PackageContext (void); - - EglTestContext& getEglTestContext (void) { return m_eglTestCtx; } - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_caseWrapper; } - -private: - EglTestContext m_eglTestCtx; - TestCaseWrapper m_caseWrapper; -}; - class TestPackage : public tcu::TestPackage { public: @@ -68,12 +41,10 @@ public: virtual void init (void); virtual void deinit (void); - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_packageCtx->getTestCaseWrapper(); } - tcu::ResourcePrefix& getArchive (void) { return m_archive; } + tcu::TestCaseExecutor* createExecutor (void) const; private: - PackageContext* m_packageCtx; - tcu::ResourcePrefix m_archive; + EglTestContext* m_eglTestCtx; }; } // egl diff --git a/modules/gles2/CMakeLists.txt b/modules/gles2/CMakeLists.txt index 053f03b..e23cb02 100644 --- a/modules/gles2/CMakeLists.txt +++ b/modules/gles2/CMakeLists.txt @@ -24,8 +24,6 @@ set(DEQP_GLES2_SRCS tes2InfoTests.hpp tes2TestCase.cpp tes2TestCase.hpp - tes2TestCaseWrapper.cpp - tes2TestCaseWrapper.hpp tes2TestPackage.cpp tes2TestPackage.hpp ) diff --git a/modules/gles2/tes2TestCaseWrapper.cpp b/modules/gles2/tes2TestCaseWrapper.cpp deleted file mode 100644 index dc3fa2c..0000000 --- a/modules/gles2/tes2TestCaseWrapper.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 2.0 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 2.0 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tes2TestCaseWrapper.hpp" -#include "tcuTestLog.hpp" -#include "gluDefs.hpp" -#include "gluStateReset.hpp" -#include "glwEnums.hpp" -#include "glwFunctions.hpp" - -namespace deqp -{ -namespace gles2 -{ - -using tcu::TestLog; - -TestCaseWrapper::TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx) - : tcu::TestCaseWrapper (testCtx) - , m_renderCtx (renderCtx) -{ - TCU_CHECK(contextSupports(renderCtx.getType(), glu::ApiType::es(2,0))); -} - -TestCaseWrapper::~TestCaseWrapper (void) -{ -} - -bool TestCaseWrapper::initTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::initTestCase(testCase); -} - -bool TestCaseWrapper::deinitTestCase (tcu::TestCase* testCase) -{ - TestLog& log = m_testCtx.getLog(); - - if (!tcu::TestCaseWrapper::deinitTestCase(testCase)) - return false; - - try - { - // Reset state - glu::resetState(m_renderCtx); - } - catch (const std::exception& e) - { - log << e; - log << TestLog::Message << "Error in state reset, test program will terminate." << TestLog::EndMessage; - return false; - } - - return true; -} - -tcu::TestNode::IterateResult TestCaseWrapper::iterateTestCase (tcu::TestCase* testCase) -{ - TestLog& log = m_testCtx.getLog(); - const glw::Functions& gl = m_renderCtx.getFunctions(); - tcu::TestCase::IterateResult result = tcu::TestNode::STOP; - - // Clear to surrender-blue - gl.clearColor(0.125f, 0.25f, 0.5f, 1.f); - gl.clear(GL_COLOR_BUFFER_BIT); - - result = tcu::TestCaseWrapper::iterateTestCase(testCase); - - // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) - try - { - m_renderCtx.postIterate(); - return result; - } - catch (const tcu::ResourceError& e) - { - m_testCtx.getLog() << e; - m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); - m_testCtx.setTerminateAfter(true); - return tcu::TestNode::STOP; - } - catch (const std::exception& e) - { - log << e; - m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); - return tcu::TestNode::STOP; - } -} - -} // gles2 -} // deqp diff --git a/modules/gles2/tes2TestCaseWrapper.hpp b/modules/gles2/tes2TestCaseWrapper.hpp deleted file mode 100644 index 3f96070..0000000 --- a/modules/gles2/tes2TestCaseWrapper.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef _TES2TESTCASEWRAPPER_HPP -#define _TES2TESTCASEWRAPPER_HPP -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 2.0 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 2.0 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tcuDefs.hpp" -#include "tcuTestCaseWrapper.hpp" -#include "gluRenderContext.hpp" - -namespace deqp -{ -namespace gles2 -{ - -class TestCaseWrapper : public tcu::TestCaseWrapper -{ -public: - TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx); - virtual ~TestCaseWrapper (void); - - virtual bool initTestCase (tcu::TestCase* testCase); - - // If deinit returns false, test execution will be aborted. - virtual bool deinitTestCase (tcu::TestCase* testCase); - virtual tcu::TestNode::IterateResult iterateTestCase (tcu::TestCase* testCase); - -private: - glu::RenderContext& m_renderCtx; -}; - -} // gles2 -} // deqp - -#endif // _TES2TESTCASEWRAPPER_HPP diff --git a/modules/gles2/tes2TestPackage.cpp b/modules/gles2/tes2TestPackage.cpp index 7eeb087..21c0abb 100644 --- a/modules/gles2/tes2TestPackage.cpp +++ b/modules/gles2/tes2TestPackage.cpp @@ -28,40 +28,93 @@ #include "tes2CapabilityTests.hpp" #include "es2aAccuracyTests.hpp" #include "es2sStressTests.hpp" +#include "tcuTestLog.hpp" +#include "gluRenderContext.hpp" +#include "gluStateReset.hpp" +#include "glwFunctions.hpp" +#include "glwEnums.hpp" namespace deqp { namespace gles2 { -PackageContext::PackageContext (tcu::TestContext& testCtx) - : m_context (DE_NULL) - , m_caseWrapper (DE_NULL) +class TestCaseWrapper : public tcu::TestCaseExecutor { +public: + TestCaseWrapper (TestPackage& package); + ~TestCaseWrapper (void); + + void init (tcu::TestCase* testCase, const std::string& path); + void deinit (tcu::TestCase* testCase); + tcu::TestNode::IterateResult iterate (tcu::TestCase* testCase); + +private: + TestPackage& m_testPackage; +}; + +TestCaseWrapper::TestCaseWrapper (TestPackage& package) + : m_testPackage(package) +{ +} + +TestCaseWrapper::~TestCaseWrapper (void) +{ +} + +void TestCaseWrapper::init (tcu::TestCase* testCase, const std::string&) +{ + testCase->init(); +} + +void TestCaseWrapper::deinit (tcu::TestCase* testCase) +{ + testCase->deinit(); + + DE_ASSERT(m_testPackage.getContext()); + glu::resetState(m_testPackage.getContext()->getRenderContext()); +} + +tcu::TestNode::IterateResult TestCaseWrapper::iterate (tcu::TestCase* testCase) +{ + tcu::TestContext& testCtx = m_testPackage.getContext()->getTestContext(); + glu::RenderContext& renderCtx = m_testPackage.getContext()->getRenderContext(); + tcu::TestCase::IterateResult result; + + // Clear to surrender-blue + { + const glw::Functions& gl = renderCtx.getFunctions(); + gl.clearColor(0.125f, 0.25f, 0.5f, 1.f); + gl.clear(GL_COLOR_BUFFER_BIT); + } + + result = testCase->iterate(); + + // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) try { - m_context = new Context(testCtx); - m_caseWrapper = new TestCaseWrapper(testCtx, m_context->getRenderContext()); + renderCtx.postIterate(); + return result; } - catch (...) + catch (const tcu::ResourceError& e) { - delete m_caseWrapper; - delete m_context; - - throw; + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); + testCtx.setTerminateAfter(true); + return tcu::TestNode::STOP; + } + catch (const std::exception& e) + { + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); + return tcu::TestNode::STOP; } -} - -PackageContext::~PackageContext (void) -{ - delete m_caseWrapper; - delete m_context; } TestPackage::TestPackage (tcu::TestContext& testCtx) : tcu::TestPackage (testCtx, "dEQP-GLES2", "dEQP OpenGL ES 2.0 Tests") - , m_packageCtx (DE_NULL) , m_archive (testCtx.getRootArchive(), "gles2/") + , m_context (DE_NULL) { } @@ -69,7 +122,7 @@ TestPackage::~TestPackage (void) { // Destroy children first since destructors may access context. TestNode::deinit(); - delete m_packageCtx; + delete m_context; } void TestPackage::init (void) @@ -77,20 +130,20 @@ void TestPackage::init (void) try { // Create context - m_packageCtx = new PackageContext(m_testCtx); + m_context = new Context(m_testCtx); // Add main test groups - addChild(new InfoTests (m_packageCtx->getContext())); - addChild(new CapabilityTests (m_packageCtx->getContext())); - addChild(new Functional::FunctionalTests (m_packageCtx->getContext())); - addChild(new Accuracy::AccuracyTests (m_packageCtx->getContext())); - addChild(new Performance::PerformanceTests (m_packageCtx->getContext())); - addChild(new Stress::StressTests (m_packageCtx->getContext())); + addChild(new InfoTests (*m_context)); + addChild(new CapabilityTests (*m_context)); + addChild(new Functional::FunctionalTests (*m_context)); + addChild(new Accuracy::AccuracyTests (*m_context)); + addChild(new Performance::PerformanceTests (*m_context)); + addChild(new Stress::StressTests (*m_context)); } catch (...) { - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; throw; } @@ -99,8 +152,13 @@ void TestPackage::init (void) void TestPackage::deinit (void) { TestNode::deinit(); - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; +} + +tcu::TestCaseExecutor* TestPackage::createExecutor (void) const +{ + return new TestCaseWrapper(const_cast(*this)); } } // gles2 diff --git a/modules/gles2/tes2TestPackage.hpp b/modules/gles2/tes2TestPackage.hpp index 3584ba0..55eadd1 100644 --- a/modules/gles2/tes2TestPackage.hpp +++ b/modules/gles2/tes2TestPackage.hpp @@ -25,7 +25,6 @@ #include "tcuDefs.hpp" #include "tcuTestPackage.hpp" -#include "tes2TestCaseWrapper.hpp" #include "tes2Context.hpp" #include "tcuResource.hpp" @@ -34,20 +33,6 @@ namespace deqp namespace gles2 { -class PackageContext -{ -public: - PackageContext (tcu::TestContext& testCtx); - ~PackageContext (void); - - Context& getContext (void) { return *m_context; } - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return *m_caseWrapper; } - -private: - Context* m_context; - TestCaseWrapper* m_caseWrapper; -}; - class TestPackage : public tcu::TestPackage { public: @@ -57,12 +42,14 @@ public: virtual void init (void); virtual void deinit (void); - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_packageCtx->getTestCaseWrapper(); } - tcu::Archive& getArchive (void) { return m_archive; } + tcu::TestCaseExecutor* createExecutor (void) const; + + tcu::Archive* getArchive (void) { return &m_archive; } + Context* getContext (void) { return m_context; } private: - PackageContext* m_packageCtx; tcu::ResourcePrefix m_archive; + Context* m_context; }; } // gles2 diff --git a/modules/gles3/CMakeLists.txt b/modules/gles3/CMakeLists.txt index e709dff..fee4280 100644 --- a/modules/gles3/CMakeLists.txt +++ b/modules/gles3/CMakeLists.txt @@ -24,8 +24,6 @@ set(DEQP_GLES3_SRCS tes3InfoTests.hpp tes3TestCase.cpp tes3TestCase.hpp - tes3TestCaseWrapper.cpp - tes3TestCaseWrapper.hpp tes3TestPackage.cpp tes3TestPackage.hpp ) diff --git a/modules/gles3/tes3TestCaseWrapper.cpp b/modules/gles3/tes3TestCaseWrapper.cpp deleted file mode 100644 index d2e2446..0000000 --- a/modules/gles3/tes3TestCaseWrapper.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 3.0 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 3.0 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tes3TestCaseWrapper.hpp" -#include "gluStateReset.hpp" -#include "tcuTestLog.hpp" -#include "glwEnums.hpp" -#include "glwFunctions.hpp" - -namespace deqp -{ -namespace gles3 -{ - -using tcu::TestLog; - -TestCaseWrapper::TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx) - : tcu::TestCaseWrapper (testCtx) - , m_renderCtx (renderCtx) -{ - TCU_CHECK(contextSupports(renderCtx.getType(), glu::ApiType::es(3,0))); -} - -TestCaseWrapper::~TestCaseWrapper (void) -{ -} - -bool TestCaseWrapper::initTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::initTestCase(testCase); -} - -bool TestCaseWrapper::deinitTestCase (tcu::TestCase* testCase) -{ - TestLog& log = m_testCtx.getLog(); - - if (!tcu::TestCaseWrapper::deinitTestCase(testCase)) - return false; - - try - { - // Reset state - glu::resetState(m_renderCtx); - } - catch (const std::exception& e) - { - log << e; - log << TestLog::Message << "Error in state reset, test program will terminate." << TestLog::EndMessage; - return false; - } - - return true; -} - -tcu::TestNode::IterateResult TestCaseWrapper::iterateTestCase (tcu::TestCase* testCase) -{ - tcu::TestCase::IterateResult result = tcu::TestNode::STOP; - - // Clear to surrender-blue - { - const glw::Functions& gl = m_renderCtx.getFunctions(); - gl.clearColor(0.125f, 0.25f, 0.5f, 1.f); - gl.clear(GL_COLOR_BUFFER_BIT); - } - - result = tcu::TestCaseWrapper::iterateTestCase(testCase); - - // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) - try - { - m_renderCtx.postIterate(); - return result; - } - catch (const tcu::ResourceError& e) - { - m_testCtx.getLog() << e; - m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); - m_testCtx.setTerminateAfter(true); - return tcu::TestNode::STOP; - } - catch (const std::exception& e) - { - m_testCtx.getLog() << e; - m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); - return tcu::TestNode::STOP; - } -} - -} // gles3 -} // deqp diff --git a/modules/gles3/tes3TestCaseWrapper.hpp b/modules/gles3/tes3TestCaseWrapper.hpp deleted file mode 100644 index 6ac92fb..0000000 --- a/modules/gles3/tes3TestCaseWrapper.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef _TES3TESTCASEWRAPPER_HPP -#define _TES3TESTCASEWRAPPER_HPP -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 3.0 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 3.0 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tcuDefs.hpp" -#include "tcuTestCaseWrapper.hpp" -#include "gluRenderContext.hpp" - -namespace deqp -{ -namespace gles3 -{ - -class TestCaseWrapper : public tcu::TestCaseWrapper -{ -public: - TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx); - virtual ~TestCaseWrapper (void); - - virtual bool initTestCase (tcu::TestCase* testCase); - - // If deinit returns false, test execution will be aborted. - virtual bool deinitTestCase (tcu::TestCase* testCase); - virtual tcu::TestNode::IterateResult iterateTestCase (tcu::TestCase* testCase); - -private: - glu::RenderContext& m_renderCtx; -}; - -} // gles3 -} // deqp - -#endif // _TES3TESTCASEWRAPPER_HPP diff --git a/modules/gles3/tes3TestPackage.cpp b/modules/gles3/tes3TestPackage.cpp index 6f569f9..f0f2289 100644 --- a/modules/gles3/tes3TestPackage.cpp +++ b/modules/gles3/tes3TestPackage.cpp @@ -27,40 +27,93 @@ #include "es3aAccuracyTests.hpp" #include "es3sStressTests.hpp" #include "es3pPerformanceTests.hpp" +#include "tcuTestLog.hpp" +#include "gluRenderContext.hpp" +#include "gluStateReset.hpp" +#include "glwFunctions.hpp" +#include "glwEnums.hpp" namespace deqp { namespace gles3 { -PackageContext::PackageContext (tcu::TestContext& testCtx) - : m_context (DE_NULL) - , m_caseWrapper (DE_NULL) +class TestCaseWrapper : public tcu::TestCaseExecutor { +public: + TestCaseWrapper (TestPackage& package); + ~TestCaseWrapper (void); + + void init (tcu::TestCase* testCase, const std::string& path); + void deinit (tcu::TestCase* testCase); + tcu::TestNode::IterateResult iterate (tcu::TestCase* testCase); + +private: + TestPackage& m_testPackage; +}; + +TestCaseWrapper::TestCaseWrapper (TestPackage& package) + : m_testPackage(package) +{ +} + +TestCaseWrapper::~TestCaseWrapper (void) +{ +} + +void TestCaseWrapper::init (tcu::TestCase* testCase, const std::string&) +{ + testCase->init(); +} + +void TestCaseWrapper::deinit (tcu::TestCase* testCase) +{ + testCase->deinit(); + + DE_ASSERT(m_testPackage.getContext()); + glu::resetState(m_testPackage.getContext()->getRenderContext()); +} + +tcu::TestNode::IterateResult TestCaseWrapper::iterate (tcu::TestCase* testCase) +{ + tcu::TestContext& testCtx = m_testPackage.getContext()->getTestContext(); + glu::RenderContext& renderCtx = m_testPackage.getContext()->getRenderContext(); + tcu::TestCase::IterateResult result; + + // Clear to surrender-blue + { + const glw::Functions& gl = renderCtx.getFunctions(); + gl.clearColor(0.125f, 0.25f, 0.5f, 1.f); + gl.clear(GL_COLOR_BUFFER_BIT); + } + + result = testCase->iterate(); + + // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) try { - m_context = new Context(testCtx); - m_caseWrapper = new TestCaseWrapper(testCtx, m_context->getRenderContext()); + renderCtx.postIterate(); + return result; } - catch (...) + catch (const tcu::ResourceError& e) { - delete m_caseWrapper; - delete m_context; - - throw; + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); + testCtx.setTerminateAfter(true); + return tcu::TestNode::STOP; + } + catch (const std::exception& e) + { + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); + return tcu::TestNode::STOP; } -} - -PackageContext::~PackageContext (void) -{ - delete m_caseWrapper; - delete m_context; } TestPackage::TestPackage (tcu::TestContext& testCtx) : tcu::TestPackage (testCtx, "dEQP-GLES3", "dEQP OpenGL ES 3.0 Tests") - , m_packageCtx (DE_NULL) , m_archive (testCtx.getRootArchive(), "gles3/") + , m_context (DE_NULL) { } @@ -68,7 +121,7 @@ TestPackage::~TestPackage (void) { // Destroy children first since destructors may access context. TestNode::deinit(); - delete m_packageCtx; + delete m_context; } void TestPackage::init (void) @@ -76,19 +129,19 @@ void TestPackage::init (void) try { // Create context - m_packageCtx = new PackageContext(m_testCtx); + m_context = new Context(m_testCtx); // Add main test groups - addChild(new InfoTests (m_packageCtx->getContext())); - addChild(new Functional::FunctionalTests (m_packageCtx->getContext())); - addChild(new Accuracy::AccuracyTests (m_packageCtx->getContext())); - addChild(new Performance::PerformanceTests (m_packageCtx->getContext())); - addChild(new Stress::StressTests (m_packageCtx->getContext())); + addChild(new InfoTests (*m_context)); + addChild(new Functional::FunctionalTests (*m_context)); + addChild(new Accuracy::AccuracyTests (*m_context)); + addChild(new Performance::PerformanceTests (*m_context)); + addChild(new Stress::StressTests (*m_context)); } catch (...) { - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; throw; } @@ -97,8 +150,13 @@ void TestPackage::init (void) void TestPackage::deinit (void) { TestNode::deinit(); - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; +} + +tcu::TestCaseExecutor* TestPackage::createExecutor (void) const +{ + return new TestCaseWrapper(const_cast(*this)); } } // gles3 diff --git a/modules/gles3/tes3TestPackage.hpp b/modules/gles3/tes3TestPackage.hpp index c58b15d..68c8cbf 100644 --- a/modules/gles3/tes3TestPackage.hpp +++ b/modules/gles3/tes3TestPackage.hpp @@ -25,7 +25,6 @@ #include "tcuDefs.hpp" #include "tcuTestPackage.hpp" -#include "tes3TestCaseWrapper.hpp" #include "tes3Context.hpp" #include "tcuResource.hpp" @@ -34,20 +33,6 @@ namespace deqp namespace gles3 { -class PackageContext -{ -public: - PackageContext (tcu::TestContext& testCtx); - ~PackageContext (void); - - Context& getContext (void) { return *m_context; } - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return *m_caseWrapper; } - -private: - Context* m_context; - TestCaseWrapper* m_caseWrapper; -}; - class TestPackage : public tcu::TestPackage { public: @@ -57,12 +42,14 @@ public: virtual void init (void); virtual void deinit (void); - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_packageCtx->getTestCaseWrapper(); } - tcu::Archive& getArchive (void) { return m_archive; } + tcu::TestCaseExecutor* createExecutor (void) const; + + tcu::Archive* getArchive (void) { return &m_archive; } + Context* getContext (void) { return m_context; } private: - PackageContext* m_packageCtx; tcu::ResourcePrefix m_archive; + Context* m_context; }; } // gles3 diff --git a/modules/gles31/CMakeLists.txt b/modules/gles31/CMakeLists.txt index 1bdf423..0d4cfc9 100644 --- a/modules/gles31/CMakeLists.txt +++ b/modules/gles31/CMakeLists.txt @@ -20,8 +20,6 @@ set(DEQP_GLES31_SRCS tes31InfoTests.hpp tes31TestCase.cpp tes31TestCase.hpp - tes31TestCaseWrapper.cpp - tes31TestCaseWrapper.hpp tes31TestPackage.cpp tes31TestPackage.hpp ) diff --git a/modules/gles31/tes31TestCase.cpp b/modules/gles31/tes31TestCase.cpp index 53af1d4..9c9c6c0 100644 --- a/modules/gles31/tes31TestCase.cpp +++ b/modules/gles31/tes31TestCase.cpp @@ -18,7 +18,9 @@ * *//*! * \file - * \brief OpenGL ES 3plus test case. + * \brief OpenGL ES 3.1 test case. *//*--------------------------------------------------------------------*/ #include "tes31TestCase.hpp" + +DE_EMPTY_CPP_FILE diff --git a/modules/gles31/tes31TestCaseWrapper.cpp b/modules/gles31/tes31TestCaseWrapper.cpp deleted file mode 100644 index e45ab8e..0000000 --- a/modules/gles31/tes31TestCaseWrapper.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 3.1 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 3.1 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tes31TestCaseWrapper.hpp" -#include "gluStateReset.hpp" -#include "tcuTestLog.hpp" -#include "glwEnums.hpp" -#include "glwFunctions.hpp" - -namespace deqp -{ -namespace gles31 -{ - -using tcu::TestLog; - -TestCaseWrapper::TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx) - : tcu::TestCaseWrapper (testCtx) - , m_renderCtx (renderCtx) -{ -// TCU_CHECK(renderCtx.getType() == glu::CONTEXTTYPE_GL43_CORE); -} - -TestCaseWrapper::~TestCaseWrapper (void) -{ -} - -bool TestCaseWrapper::initTestCase (tcu::TestCase* testCase) -{ - return tcu::TestCaseWrapper::initTestCase(testCase); -} - -bool TestCaseWrapper::deinitTestCase (tcu::TestCase* testCase) -{ - TestLog& log = m_testCtx.getLog(); - - if (!tcu::TestCaseWrapper::deinitTestCase(testCase)) - return false; - - try - { - // Reset state - glu::resetState(m_renderCtx); - } - catch (const std::exception& e) - { - log << e; - log << TestLog::Message << "Error in state reset, test program will terminate." << TestLog::EndMessage; - return false; - } - - return true; -} - -tcu::TestNode::IterateResult TestCaseWrapper::iterateTestCase (tcu::TestCase* testCase) -{ - tcu::TestCase::IterateResult result = tcu::TestCaseWrapper::iterateTestCase(testCase); - - // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) - try - { - m_renderCtx.postIterate(); - return result; - } - catch (const tcu::ResourceError& e) - { - m_testCtx.getLog() << e; - m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); - m_testCtx.setTerminateAfter(true); - return tcu::TestNode::STOP; - } - catch (const std::exception& e) - { - m_testCtx.getLog() << e; - m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); - return tcu::TestNode::STOP; - } -} - -} // gles31 -} // deqp diff --git a/modules/gles31/tes31TestCaseWrapper.hpp b/modules/gles31/tes31TestCaseWrapper.hpp deleted file mode 100644 index 941e7f7..0000000 --- a/modules/gles31/tes31TestCaseWrapper.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef _TES31TESTCASEWRAPPER_HPP -#define _TES31TESTCASEWRAPPER_HPP -/*------------------------------------------------------------------------- - * drawElements Quality Program OpenGL ES 3.1 Module - * ------------------------------------------------- - * - * 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 OpenGL ES 3.1 Test Case Wrapper. - *//*--------------------------------------------------------------------*/ - -#include "tcuDefs.hpp" -#include "tcuTestCaseWrapper.hpp" -#include "gluRenderContext.hpp" - -namespace deqp -{ -namespace gles31 -{ - -class TestCaseWrapper : public tcu::TestCaseWrapper -{ -public: - TestCaseWrapper (tcu::TestContext& testCtx, glu::RenderContext& renderCtx); - virtual ~TestCaseWrapper (void); - - virtual bool initTestCase (tcu::TestCase* testCase); - - // If deinit returns false, test execution will be aborted. - virtual bool deinitTestCase (tcu::TestCase* testCase); - virtual tcu::TestNode::IterateResult iterateTestCase (tcu::TestCase* testCase); - -private: - glu::RenderContext& m_renderCtx; -}; - -} // gles31 -} // deqp - -#endif // _TES31TESTCASEWRAPPER_HPP diff --git a/modules/gles31/tes31TestPackage.cpp b/modules/gles31/tes31TestPackage.cpp index 54ce5aa..51a1be9 100644 --- a/modules/gles31/tes31TestPackage.cpp +++ b/modules/gles31/tes31TestPackage.cpp @@ -25,40 +25,81 @@ #include "tes31InfoTests.hpp" #include "es31fFunctionalTests.hpp" #include "es31sStressTests.hpp" +#include "gluStateReset.hpp" +#include "gluRenderContext.hpp" +#include "tcuTestLog.hpp" namespace deqp { namespace gles31 { -PackageContext::PackageContext (tcu::TestContext& testCtx) - : m_context (DE_NULL) - , m_caseWrapper (DE_NULL) +class TestCaseWrapper : public tcu::TestCaseExecutor { +public: + TestCaseWrapper (TestPackage& package); + ~TestCaseWrapper (void); + + void init (tcu::TestCase* testCase, const std::string& path); + void deinit (tcu::TestCase* testCase); + tcu::TestNode::IterateResult iterate (tcu::TestCase* testCase); + +private: + TestPackage& m_testPackage; +}; + +TestCaseWrapper::TestCaseWrapper (TestPackage& package) + : m_testPackage(package) +{ +} + +TestCaseWrapper::~TestCaseWrapper (void) +{ +} + +void TestCaseWrapper::init (tcu::TestCase* testCase, const std::string&) +{ + testCase->init(); +} + +void TestCaseWrapper::deinit (tcu::TestCase* testCase) +{ + testCase->deinit(); + + DE_ASSERT(m_testPackage.getContext()); + glu::resetState(m_testPackage.getContext()->getRenderContext()); +} + +tcu::TestNode::IterateResult TestCaseWrapper::iterate (tcu::TestCase* testCase) +{ + tcu::TestContext& testCtx = m_testPackage.getContext()->getTestContext(); + const tcu::TestCase::IterateResult result = testCase->iterate(); + + // Call implementation specific post-iterate routine (usually handles native events and swaps buffers) try { - m_context = new Context(testCtx); - m_caseWrapper = new TestCaseWrapper(testCtx, m_context->getRenderContext()); + m_testPackage.getContext()->getRenderContext().postIterate(); + return result; } - catch (...) + catch (const tcu::ResourceError& e) { - delete m_caseWrapper; - delete m_context; - - throw; + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Resource error in context post-iteration routine"); + testCtx.setTerminateAfter(true); + return tcu::TestNode::STOP; + } + catch (const std::exception& e) + { + testCtx.getLog() << e; + testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error in context post-iteration routine"); + return tcu::TestNode::STOP; } -} - -PackageContext::~PackageContext (void) -{ - delete m_caseWrapper; - delete m_context; } TestPackage::TestPackage (tcu::TestContext& testCtx) : tcu::TestPackage (testCtx, "dEQP-GLES31", "dEQP OpenGL ES 3.1 Tests") - , m_packageCtx (DE_NULL) , m_archive (testCtx.getRootArchive(), "gles31/") + , m_context (DE_NULL) { } @@ -66,7 +107,7 @@ TestPackage::~TestPackage (void) { // Destroy children first since destructors may access context. TestNode::deinit(); - delete m_packageCtx; + delete m_context; } void TestPackage::init (void) @@ -74,17 +115,17 @@ void TestPackage::init (void) try { // Create context - m_packageCtx = new PackageContext(m_testCtx); + m_context = new Context(m_testCtx); // Add main test groups - addChild(new InfoTests (m_packageCtx->getContext())); - addChild(new Functional::FunctionalTests (m_packageCtx->getContext())); - addChild(new Stress::StressTests (m_packageCtx->getContext())); + addChild(new InfoTests (*m_context)); + addChild(new Functional::FunctionalTests (*m_context)); + addChild(new Stress::StressTests (*m_context)); } catch (...) { - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; throw; } @@ -93,8 +134,13 @@ void TestPackage::init (void) void TestPackage::deinit (void) { TestNode::deinit(); - delete m_packageCtx; - m_packageCtx = DE_NULL; + delete m_context; + m_context = DE_NULL; +} + +tcu::TestCaseExecutor* TestPackage::createExecutor (void) const +{ + return new TestCaseWrapper(const_cast(*this)); } } // gles31 diff --git a/modules/gles31/tes31TestPackage.hpp b/modules/gles31/tes31TestPackage.hpp index cfe339b..1372f83 100644 --- a/modules/gles31/tes31TestPackage.hpp +++ b/modules/gles31/tes31TestPackage.hpp @@ -25,7 +25,6 @@ #include "tcuDefs.hpp" #include "tcuTestPackage.hpp" -#include "tes31TestCaseWrapper.hpp" #include "tes31Context.hpp" #include "tcuResource.hpp" @@ -34,20 +33,6 @@ namespace deqp namespace gles31 { -class PackageContext -{ -public: - PackageContext (tcu::TestContext& testCtx); - ~PackageContext (void); - - Context& getContext (void) { return *m_context; } - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return *m_caseWrapper; } - -private: - Context* m_context; - TestCaseWrapper* m_caseWrapper; -}; - class TestPackage : public tcu::TestPackage { public: @@ -57,12 +42,14 @@ public: virtual void init (void); virtual void deinit (void); - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_packageCtx->getTestCaseWrapper(); } - tcu::Archive& getArchive (void) { return m_archive; } + tcu::TestCaseExecutor* createExecutor (void) const; + + tcu::Archive* getArchive (void) { return &m_archive; } + Context* getContext (void) { return m_context; } private: - PackageContext* m_packageCtx; tcu::ResourcePrefix m_archive; + Context* m_context; }; } // gles31 diff --git a/modules/internal/ditImageCompareTests.cpp b/modules/internal/ditImageCompareTests.cpp index 96e0a5f..899b488 100644 --- a/modules/internal/ditImageCompareTests.cpp +++ b/modules/internal/ditImageCompareTests.cpp @@ -38,7 +38,7 @@ namespace dit using tcu::TestLog; -static const char* BASE_DIR = "data/imagecompare"; +static const char* BASE_DIR = "internal/data/imagecompare"; static void loadImageRGBA8 (tcu::TextureLevel& dst, const tcu::Archive& archive, const char* path) { diff --git a/modules/internal/ditImageIOTests.cpp b/modules/internal/ditImageIOTests.cpp index fde67f3..c9a7178 100644 --- a/modules/internal/ditImageIOTests.cpp +++ b/modules/internal/ditImageIOTests.cpp @@ -90,10 +90,10 @@ public: void init (void) { - addChild(new ImageReadCase(m_testCtx, "rgb24_256x256", "data/imageio/rgb24_256x256.png", 0x6efad777)); - addChild(new ImageReadCase(m_testCtx, "rgb24_209x181", "data/imageio/rgb24_209x181.png", 0xfd6ea668)); - addChild(new ImageReadCase(m_testCtx, "rgba32_256x256", "data/imageio/rgba32_256x256.png", 0xcf4883da)); - addChild(new ImageReadCase(m_testCtx, "rgba32_207x219", "data/imageio/rgba32_207x219.png", 0x404ba06b)); + addChild(new ImageReadCase(m_testCtx, "rgb24_256x256", "internal/data/imageio/rgb24_256x256.png", 0x6efad777)); + addChild(new ImageReadCase(m_testCtx, "rgb24_209x181", "internal/data/imageio/rgb24_209x181.png", 0xfd6ea668)); + addChild(new ImageReadCase(m_testCtx, "rgba32_256x256", "internal/data/imageio/rgba32_256x256.png", 0xcf4883da)); + addChild(new ImageReadCase(m_testCtx, "rgba32_207x219", "internal/data/imageio/rgba32_207x219.png", 0x404ba06b)); } }; diff --git a/modules/internal/ditTestPackage.cpp b/modules/internal/ditTestPackage.cpp index 22c75b2..e2be5cd 100644 --- a/modules/internal/ditTestPackage.cpp +++ b/modules/internal/ditTestPackage.cpp @@ -50,9 +50,35 @@ public: } }; +class TestCaseExecutor : public tcu::TestCaseExecutor +{ +public: + TestCaseExecutor (void) + { + } + + ~TestCaseExecutor (void) + { + } + + void init (tcu::TestCase* testCase, const std::string&) + { + testCase->init(); + } + + void deinit (tcu::TestCase* testCase) + { + testCase->deinit(); + } + + tcu::TestNode::IterateResult iterate (tcu::TestCase* testCase) + { + return testCase->iterate(); + } +}; + TestPackage::TestPackage (tcu::TestContext& testCtx) : tcu::TestPackage (testCtx, "dE-IT", "drawElements Internal Tests") - , m_wrapper (testCtx) , m_archive (testCtx.getRootArchive(), "internal/") { } @@ -69,9 +95,9 @@ void TestPackage::init (void) addChild(new DeqpTests (m_testCtx)); } -void TestPackage::deinit (void) +tcu::TestCaseExecutor* TestPackage::createExecutor (void) const { - TestNode::deinit(); + return new TestCaseExecutor(); } } // dit diff --git a/modules/internal/ditTestPackage.hpp b/modules/internal/ditTestPackage.hpp index 0d08a06..c42a9ee 100644 --- a/modules/internal/ditTestPackage.hpp +++ b/modules/internal/ditTestPackage.hpp @@ -37,13 +37,10 @@ public: virtual ~TestPackage (void); virtual void init (void); - virtual void deinit (void); - - tcu::TestCaseWrapper& getTestCaseWrapper (void) { return m_wrapper; } - tcu::Archive& getArchive (void) { return m_archive; } + tcu::TestCaseExecutor* createExecutor (void) const; + tcu::Archive* getArchive (void) { return &m_archive; } private: - tcu::TestCaseWrapper m_wrapper; tcu::ResourcePrefix m_archive; }; -- 2.7.4