Commit 6ba49d94 by Geoff Lang

Automate the es conformance tests by wrapping them in the gtest suite.

BUG=angle:497 Change-Id: If12b2dd79f9f666c5d686237d5663f316171b15c Reviewed-on: https://chromium-review.googlesource.com/200043Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent c600c8c3
import os
import re
import sys
def ReadFileAsLines(filename):
"""Reads a file, removing blank lines and lines that start with #"""
file = open(filename, "r")
raw_lines = file.readlines()
file.close()
lines = []
for line in raw_lines:
line = line.strip()
if len(line) > 0 and not line.startswith("#"):
lines.append(line)
return lines
def GetSuiteName(testName):
return testName[:testName.find("/")]
def GetTestName(testName):
replacements = { ".test": "", ".": "_" }
splitTestName = testName.split("/")
cleanName = splitTestName[-2] + "_" + splitTestName[-1]
for replaceKey in replacements:
cleanName = cleanName.replace(replaceKey, replacements[replaceKey])
return cleanName
def GenerateTests(outFile, testNames):
# Remove duplicate tests
testNames = list(set(testNames))
outFile.write("#include \"gles_conformance_tests.h\"\n\n")
for test in testNames:
outFile.write("TEST(" + GetSuiteName(test) + ", " + GetTestName(test) + ")\n")
outFile.write("{\n")
outFile.write(" RunConformanceTest(\"" + test + "\", GetCurrentConfig());\n")
outFile.write("}\n\n")
def GenerateTestList(sourceFile, rootDir):
tests = [ ]
fileName, fileExtension = os.path.splitext(sourceFile)
if fileExtension == ".run":
lines = ReadFileAsLines(sourceFile)
for line in lines:
tests += GenerateTestList(os.path.join(os.path.dirname(sourceFile), line), rootDir)
elif fileExtension == ".test":
tests.append(os.path.relpath(os.path.realpath(sourceFile), rootDir).replace("\\", "/"))
return tests;
def main(argv):
tests = GenerateTestList(argv[0], argv[1])
tests.sort()
output = open(argv[2], 'wb')
GenerateTests(output, tests)
output.close()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
#include "gles_conformance_tests.h"
#include "GTFMain.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <stdarg.h>
static ConformanceConfig kCurrentConfig = { 64, 64, EGL_DEFAULT_DISPLAY };
void SetCurrentConfig(const ConformanceConfig& config)
{
kCurrentConfig = config;
}
const ConformanceConfig& GetCurrentConfig()
{
return kCurrentConfig;
}
static std::vector<char> FormatArg(const char* fmt, ...)
{
va_list vararg;
va_start(vararg, fmt);
int len = vsnprintf(NULL, 0, fmt, vararg);
va_end(vararg);
std::vector<char> buf(len + 1);
va_start(vararg, fmt);
vsnprintf(buf.data(), buf.size(), fmt, vararg);
va_end(vararg);
return buf;
}
static std::string GetExecutableDirectory()
{
std::vector<char> executableFileBuf(MAX_PATH);
DWORD executablePathLen = GetModuleFileNameA(NULL, executableFileBuf.data(), executableFileBuf.size());
if (executablePathLen == 0)
{
return false;
}
std::string executableLocation = executableFileBuf.data();
size_t lastPathSepLoc = executableLocation.find_last_of("\\/");
if (lastPathSepLoc != std::string::npos)
{
executableLocation = executableLocation.substr(0, lastPathSepLoc);
}
else
{
executableLocation = "";
}
return executableLocation;
}
void RunConformanceTest(const std::string &testPath, const ConformanceConfig& config)
{
std::vector<char*> args;
// Empty first argument for the program name
args.push_back("");
std::vector<char> widthArg = FormatArg("-width=%u", config.width);
args.push_back(widthArg.data());
std::vector<char> heightArg = FormatArg("-height=%u", config.height);
args.push_back(heightArg.data());
std::vector<char> displayArg = FormatArg("-d=%u", config.displayType);
args.push_back(displayArg.data());
std::vector<char> runArg = FormatArg("-run=%s/conformance_tests/%s", GetExecutableDirectory().c_str(), testPath.c_str());
args.push_back(runArg.data());
// Redirect cout
std::streambuf* oldCoutStreamBuf = std::cout.rdbuf();
std::ostringstream strCout;
std::cout.rdbuf(strCout.rdbuf());
if (GTFMain(args.size(), args.data()) != 0)
{
FAIL() << "GTFMain failed.";
}
// Restore old cout
std::cout.rdbuf(oldCoutStreamBuf);
std::string log = strCout.str();
// Look for failures
size_t offset = 0;
std::string offsetSearchString = "failure = ";
while ((offset = log.find("failure = ", offset)) != std::string::npos)
{
offset += offsetSearchString.length();
size_t failureCount = atoll(log.c_str() + offset);
EXPECT_EQ(0, failureCount) << log;
}
}
//
// Copyright (c) 2014 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.
//
#ifndef CONFORMANCE_TESTS_CONFORMANCE_TEST_H_
#define CONFORMANCE_TESTS_CONFORMANCE_TEST_H_
#include "gtest/gtest.h"
#include <EGL/egl.h>
#include <string>
struct ConformanceConfig
{
size_t width;
size_t height;
EGLNativeDisplayType displayType;
};
void SetCurrentConfig(const ConformanceConfig& config);
const ConformanceConfig& GetCurrentConfig();
void RunConformanceTest(const std::string &testPath, const ConformanceConfig& config);
#endif // CONFORMANCE_TESTS_CONFORMANCE_TEST_H_
//
// Copyright (c) 2014 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.
//
#include "gles_conformance_tests.h"
#include "gtest/gtest.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <map>
#include <string>
#include <vector>
#define CONFORMANCE_TESTS_ES2 2
#define CONFORMANCE_TESTS_ES3 3
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
typedef std::pair<std::string, EGLNativeDisplayType> NameDisplayTypePair;
typedef std::map<std::string, EGLNativeDisplayType> DisplayTypeMap;
DisplayTypeMap allDisplays;
#if CONFORMANCE_TESTS_TYPE == CONFORMANCE_TESTS_ES2
allDisplays["d3d9"] = EGL_DEFAULT_DISPLAY;
allDisplays["d3d11"] = EGL_D3D11_ONLY_DISPLAY_ANGLE;
#elif CONFORMANCE_TESTS_TYPE == CONFORMANCE_TESTS_ES3
allDisplays["d3d11"] = EGL_D3D11_ONLY_DISPLAY_ANGLE;
#else
# error "Unknown CONFORMANCE_TESTS_TYPE"
#endif
// Iterate through the command line arguments and check if they are config names
std::vector<NameDisplayTypePair> requestedDisplays;
for (size_t i = 1; i < static_cast<size_t>(argc); i++)
{
DisplayTypeMap::const_iterator iter = allDisplays.find(argv[i]);
if (iter != allDisplays.end())
{
requestedDisplays.push_back(*iter);
}
}
// If no configs were requested, run them all
if (requestedDisplays.empty())
{
for (DisplayTypeMap::const_iterator i = allDisplays.begin(); i != allDisplays.end(); i++)
{
requestedDisplays.push_back(*i);
}
}
// Run each requested config
int rt = 0;
for (size_t i = 0; i < requestedDisplays.size(); i++)
{
ConformanceConfig config = { 64, 64, requestedDisplays[i].second };
SetCurrentConfig(config);
std::cout << "Running test configuration \"" << requestedDisplays[i].first << "\".\n";
rt |= RUN_ALL_TESTS();
}
return rt;
}
......@@ -3,6 +3,10 @@
# found in the LICENSE file.
{
'variables':
{
'angle_build_conformance_tests%': '0',
},
'targets':
[
{
......@@ -159,6 +163,137 @@
],
},
],
'conditions':
[
['angle_build_conformance_tests',
{
'variables':
{
'gles_conformance_tests_output_dir': '<(SHARED_INTERMEDIATE_DIR)/conformance_tests',
'gles_conformance_tests_input_dir': 'third_party/gles_conformance_tests/conform/GTF_ES/glsl/GTF',
'gles_conformance_tests_generator_script': 'gles_conformance_tests/generate_gles_conformance_tests.py',
},
'targets':
[
{
'target_name': 'gles2_conformance_tests',
'type': 'executable',
'includes': [ '../build/common_defines.gypi', ],
'dependencies':
[
'../src/angle.gyp:libGLESv2',
'../src/angle.gyp:libEGL',
'gtest',
'third_party/gles_conformance_tests/conform/GTF_ES/glsl/GTF/es_cts.gyp:es_cts_test_data',
'third_party/gles_conformance_tests/conform/GTF_ES/glsl/GTF/es_cts.gyp:es2_cts',
],
'variables':
{
'gles2_conformance_tests_input_file': '<(gles_conformance_tests_input_dir)/mustpass_es20.run',
'gles2_conformance_tests_generated_file': '<(gles_conformance_tests_output_dir)/generated_gles2_conformance_tests.cpp',
},
'sources':
[
'<!@(python <(angle_path)/enumerate_files.py gles_conformance_tests -types *.cpp *.h *.inl)',
'<(gles2_conformance_tests_generated_file)',
],
'include_dirs':
[
'../include',
'gles_conformance_tests',
'third_party/googletest/include',
],
'defines':
[
'CONFORMANCE_TESTS_TYPE=CONFORMANCE_TESTS_ES2',
],
'actions':
[
{
'action_name': 'generate_gles2_conformance_tests',
'message': 'Generating ES2 conformance tests...',
'msvs_cygwin_shell': 0,
'inputs':
[
'<(gles_conformance_tests_generator_script)',
'<(gles2_conformance_tests_input_file)',
],
'outputs':
[
'<(gles2_conformance_tests_generated_file)',
],
'action':
[
'python',
'<(gles_conformance_tests_generator_script)',
'<(gles2_conformance_tests_input_file)',
'<(gles_conformance_tests_input_dir)',
'<(gles2_conformance_tests_generated_file)',
],
},
],
},
{
'target_name': 'gles3_conformance_tests',
'type': 'executable',
'includes': [ '../build/common_defines.gypi', ],
'dependencies':
[
'../src/angle.gyp:libGLESv2',
'../src/angle.gyp:libEGL',
'gtest',
'third_party/gles_conformance_tests/conform/GTF_ES/glsl/GTF/es_cts.gyp:es_cts_test_data',
'third_party/gles_conformance_tests/conform/GTF_ES/glsl/GTF/es_cts.gyp:es3_cts',
],
'variables':
{
'gles3_conformance_tests_input_file': '<(gles_conformance_tests_input_dir)/mustpass_es30.run',
'gles3_conformance_tests_generated_file': '<(gles_conformance_tests_output_dir)/generated_gles3_conformance_tests.cpp',
},
'sources':
[
'<!@(python <(angle_path)/enumerate_files.py gles_conformance_tests -types *.cpp *.h *.inl)',
'<(gles3_conformance_tests_generated_file)',
],
'include_dirs':
[
'../include',
'gles_conformance_tests',
'third_party/googletest/include',
],
'defines':
[
'CONFORMANCE_TESTS_TYPE=CONFORMANCE_TESTS_ES3',
],
'actions':
[
{
'action_name': 'generate_gles3_conformance_tests',
'message': 'Generating ES3 conformance tests...',
'msvs_cygwin_shell': 0,
'inputs':
[
'<(gles_conformance_tests_generator_script)',
'<(gles3_conformance_tests_input_file)',
],
'outputs':
[
'<(gles3_conformance_tests_generated_file)',
],
'action':
[
'python',
'<(gles_conformance_tests_generator_script)',
'<(gles3_conformance_tests_input_file)',
'<(gles_conformance_tests_input_dir)',
'<(gles3_conformance_tests_generated_file)',
],
},
],
},
],
}],
],
}],
],
}
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