Commit 7f165fd9 by Jamie Madill

dEQP: Hook up GPU test expectations code.

With the list of failures, this gives a 100% passing GLES2 test suite. BUG=angleproject:998 Change-Id: I20985c729104d7a114352d156c238bca3ea1698c Reviewed-on: https://chromium-review.googlesource.com/274423Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 6ffeb744
...@@ -1129,55 +1129,67 @@ ...@@ -1129,55 +1129,67 @@
], ],
}, },
# Helper target for synching our implementation with chrome's
{ {
'target_name': 'angle_deqp_googletest', 'target_name': 'angle_deqp_gtest_support',
'type': 'executable', 'type': 'none',
'dependencies': 'dependencies':
[ [
'angle_deqp_libgles2', 'angle_deqp_libgles2',
'angle_test_support', 'angle_test_support',
'angle_zlib', 'angle_zlib',
'angle_deqp_decpp',
'<(angle_path)/src/angle.gyp:angle_common', '<(angle_path)/src/angle.gyp:angle_common',
], ],
'includes': 'export_dependent_settings':
[ [
'../../build/common_defines.gypi', 'angle_test_support',
'angle_zlib',
'angle_deqp_decpp',
'<(angle_path)/src/angle.gyp:angle_common',
], ],
'defines': 'direct_dependent_settings':
{
'defines':
[
# Hard-code the path to dEQP. This lets the
# app locate the data folder without need
# for a copy. gyp recursive copies are not
# implemented properly on Windows.
'ANGLE_DEQP_DIR="<(DEPTH)/src/tests/<(deqp_dir)"',
],
'include_dirs':
[
'deqp_support',
],
'sources':
[
'deqp_support/angle_deqp_gtest.cpp',
],
},
},
{
'target_name': 'angle_deqp_googletest',
'type': 'executable',
'dependencies':
[ [
# Hard-code the path to dEQP. This lets the 'angle_deqp_gtest_support',
# app locate the data folder without need
# for a copy. gyp recursive copies are not
# implemented properly on Windows.
'ANGLE_DEQP_DIR="<(DEPTH)/src/tests/<(deqp_dir)"',
], ],
'include_dirs': 'include_dirs':
[ [
'deqp_support',
'third_party/gpu_test_expectations', 'third_party/gpu_test_expectations',
], ],
'sources': 'sources':
[ [
'deqp_support/angle_deqp_gtest_main.cpp', 'deqp_support/angle_deqp_gtest_main.cpp',
], 'third_party/gpu_test_expectations/gpu_info.cc',
'third_party/gpu_test_expectations/gpu_info.h',
'conditions': 'third_party/gpu_test_expectations/gpu_test_config.cc',
[ 'third_party/gpu_test_expectations/gpu_test_config.h',
['angle_standalone==1', 'third_party/gpu_test_expectations/gpu_test_expectations_parser.cc',
{ 'third_party/gpu_test_expectations/gpu_test_expectations_parser.h',
'sources':
[
'third_party/gpu_test_expectations/gpu_info.cc',
'third_party/gpu_test_expectations/gpu_info.h',
'third_party/gpu_test_expectations/gpu_test_config.cc',
'third_party/gpu_test_expectations/gpu_test_config.h',
'third_party/gpu_test_expectations/gpu_test_expectations_parser.cc',
'third_party/gpu_test_expectations/gpu_test_expectations_parser.h',
],
}]
], ],
}, },
], # targets ], # targets
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// angle_deqp_gtest:
// dEQP and GoogleTest integration logic. Calls through to the random
// order executor.
#include <gtest/gtest.h>
#include <stdint.h>
#include <zlib.h>
#include <algorithm>
#include <fstream>
#include "angle_deqp_libtester.h"
#include "common/angleutils.h"
#include "common/debug.h"
#include "gpu_test_expectations_parser.h"
namespace
{
class dEQPCaseList
{
public:
dEQPCaseList(const char *caseListPath, const char *testExpectationsPath);
struct CaseInfo
{
CaseInfo(const std::string &dEQPName,
const std::string &gTestName,
int expectation)
: mDEQPName(dEQPName),
mGTestName(gTestName),
mExpectation(expectation)
{
}
std::string mDEQPName;
std::string mGTestName;
int mExpectation;
};
const CaseInfo &getCaseInfo(size_t caseIndex) const
{
ASSERT(caseIndex < mCaseInfoList.size());
return mCaseInfoList[caseIndex];
}
size_t numCases() const
{
return mCaseInfoList.size();
}
static dEQPCaseList *GetInstance();
static void FreeInstance();
private:
std::vector<CaseInfo> mCaseInfoList;
gpu::GPUTestExpectationsParser mTestExpectationsParser;
gpu::GPUTestBotConfig mTestConfig;
static dEQPCaseList *mInstance;
};
// static
dEQPCaseList *dEQPCaseList::mInstance = nullptr;
// static
dEQPCaseList *dEQPCaseList::GetInstance()
{
if (mInstance == nullptr)
{
mInstance = new dEQPCaseList("deqp_support/dEQP-GLES2-cases.txt.gz",
"deqp_support/deqp_test_expectations.txt");
}
return mInstance;
}
// Not currently called, assumed to be freed on program exit.
// static
void dEQPCaseList::FreeInstance()
{
SafeDelete(mInstance);
}
dEQPCaseList::dEQPCaseList(const char *caseListPath, const char *testExpectationsPath)
{
if (!mTestExpectationsParser.LoadTestExpectationsFromFile(std::string(testExpectationsPath)))
{
std::cerr << "Failed to load test expectations." << std::endl;
for (const auto &message : mTestExpectationsParser.GetErrorMessages())
{
std::cerr << " " << message << std::endl;
}
return;
}
if (!mTestConfig.LoadCurrentConfig(nullptr))
{
std::cerr << "Failed to load test configuration." << std::endl;
return;
}
std::stringstream caseListStream;
std::vector<char> buf(1024 * 1024 * 16);
gzFile *fi = static_cast<gzFile *>(gzopen(caseListPath, "rb"));
if (fi == nullptr)
{
return;
}
gzrewind(fi);
while (!gzeof(fi))
{
int len = gzread(fi, &buf[0], static_cast<unsigned int>(buf.size()) - 1);
buf[len] = '\0';
caseListStream << &buf[0];
}
gzclose(fi);
while (!caseListStream.eof())
{
std::string inString;
std::getline(caseListStream, inString);
if (inString.substr(0, 4) == "TEST")
{
std::string dEQPName = inString.substr(6);
std::string gTestName = dEQPName.substr(11);
std::replace(gTestName.begin(), gTestName.end(), '.', '_');
// Occurs in some luminance tests
gTestName.erase(std::remove(gTestName.begin(), gTestName.end(), '-'), gTestName.end());
int expectation = mTestExpectationsParser.GetTestExpectation(dEQPName, mTestConfig);
if (expectation != gpu::GPUTestExpectationsParser::kGpuTestSkip)
{
mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation));
}
}
}
}
class dEQP_GLES2 : public testing::TestWithParam<size_t>
{
protected:
dEQP_GLES2() {}
void runTest()
{
const auto &caseInfo = dEQPCaseList::GetInstance()->getCaseInfo(GetParam());
std::cout << caseInfo.mDEQPName << std::endl;
bool result = deqp_libtester_run(caseInfo.mDEQPName.c_str());
if (caseInfo.mExpectation == gpu::GPUTestExpectationsParser::kGpuTestPass)
{
EXPECT_TRUE(result);
}
else if (result)
{
std::cout << "Test expected to fail but passed!" << std::endl;
}
}
};
// TODO(jmadill): add different platform configs, or ability to choose platform
TEST_P(dEQP_GLES2, Default)
{
runTest();
}
testing::internal::ParamGenerator<size_t> GetTestingRange()
{
return testing::Range<size_t>(0, dEQPCaseList::GetInstance()->numCases());
}
INSTANTIATE_TEST_CASE_P(, dEQP_GLES2, GetTestingRange());
} // anonymous namespace
...@@ -4,154 +4,17 @@ ...@@ -4,154 +4,17 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// angle_deqp_gtest_main: // angle_deqp_gtest_main:
// dEQP and GoogleTest integration logic. Calls through to the random // Entry point for standalone dEQP tests.
// order executor.
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <stdint.h>
#include <zlib.h>
#include <algorithm>
#include <fstream>
#include "angle_deqp_libtester.h" #include "angle_deqp_libtester.h"
#include "common/angleutils.h"
#include "common/debug.h"
namespace
{
class dEQPCaseList
{
public:
dEQPCaseList(const char *caseListPath);
struct CaseInfo
{
CaseInfo(const std::string &dEQPName,
const std::string &gTestName)
: mDEQPName(dEQPName),
mGTestName(gTestName)
{
}
std::string mDEQPName;
std::string mGTestName;
};
const CaseInfo &getCaseInfo(size_t caseIndex) const
{
ASSERT(caseIndex < mCaseInfoList.size());
return mCaseInfoList[caseIndex];
}
size_t numCases() const
{
return mCaseInfoList.size();
}
static dEQPCaseList *GetInstance();
static void FreeInstance();
private:
std::vector<CaseInfo> mCaseInfoList;
static dEQPCaseList *mInstance;
};
// static
dEQPCaseList *dEQPCaseList::mInstance = nullptr;
// static
dEQPCaseList *dEQPCaseList::GetInstance()
{
if (mInstance == nullptr)
{
mInstance = new dEQPCaseList("deqp_support/dEQP-GLES2-cases.txt.gz");
}
return mInstance;
}
// static
void dEQPCaseList::FreeInstance()
{
SafeDelete(mInstance);
}
dEQPCaseList::dEQPCaseList(const char *caseListPath)
{
std::stringstream caseListStream;
std::vector<char> buf(1024 * 1024 * 16);
gzFile *fi = static_cast<gzFile *>(gzopen(caseListPath, "rb"));
if (fi == nullptr)
{
return;
}
gzrewind(fi);
while (!gzeof(fi))
{
int len = gzread(fi, &buf[0], buf.size() - 1);
buf[len] = '\0';
caseListStream << &buf[0];
}
gzclose(fi);
while (!caseListStream.eof())
{
std::string inString;
std::getline(caseListStream, inString);
if (inString.substr(0, 4) == "TEST")
{
std::string dEQPName = inString.substr(6);
std::string gTestName = dEQPName.substr(11);
std::replace(gTestName.begin(), gTestName.end(), '.', '_');
// Occurs in some luminance tests
gTestName.erase(std::remove(gTestName.begin(), gTestName.end(), '-'), gTestName.end());
mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName));
}
}
}
class dEQP_GLES2 : public testing::TestWithParam<size_t>
{
protected:
dEQP_GLES2() {}
void runTest()
{
const auto &caseInfo = dEQPCaseList::GetInstance()->getCaseInfo(GetParam());
std::cout << caseInfo.mDEQPName << std::endl;
ASSERT_TRUE(deqp_libtester_run(caseInfo.mDEQPName.c_str()));
}
};
// TODO(jmadill): add different platform configs, or ability to choose platform
TEST_P(dEQP_GLES2, Default)
{
runTest();
}
testing::internal::ParamGenerator<size_t> GetTestingRange()
{
return testing::Range<size_t>(0, dEQPCaseList::GetInstance()->numCases());
}
INSTANTIATE_TEST_CASE_P(, dEQP_GLES2, GetTestingRange());
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
deqp_libtester_init_platform(argc, argv, ANGLE_DEQP_DIR "/data"); deqp_libtester_init_platform(argc, argv, ANGLE_DEQP_DIR "/data");
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
int rt = RUN_ALL_TESTS(); int rt = RUN_ALL_TESTS();
dEQPCaseList::FreeInstance();
deqp_libtester_shutdown_platform(); deqp_libtester_shutdown_platform();
return rt; return rt;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment