Commit c832cdd7 by Jonah Ryan-Davis Committed by Commit Bot

dEQP test_expectations parser should output an error on unused lines.

dEQP test_expectations parser should allow nested overrides. When an expectation line is not used for any test, it's likely duplicated or misspelled, or the test was removed. The parser should output these errors to make it easier to keep the expectations up to date. Also necessary to allow longer/more specific expectations to override shorter ones, so the scenario where you FAIL one set of tests across platforms, and SKIP a subset of that group on one platform will still be allowed. Bug: angleproject:3368 Change-Id: If0470cb6fb12f8d3daa97df0c701185fa086668c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1564725 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent b8a8ffd3
...@@ -296,6 +296,19 @@ void dEQPCaseList::initialize() ...@@ -296,6 +296,19 @@ void dEQPCaseList::initialize()
int expectation = mTestExpectationsParser.getTestExpectation(dEQPName); int expectation = mTestExpectationsParser.getTestExpectation(dEQPName);
mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation)); mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation));
} }
std::stringstream unusedMsgStream;
bool anyUnused = false;
for (const auto &message : mTestExpectationsParser.getUnusedExpectationsMessages())
{
anyUnused = true;
unusedMsgStream << std::endl << " " << message;
}
if (anyUnused)
{
std::cerr << "Failed to validate test expectations." << unusedMsgStream.str() << std::endl;
Die();
}
} }
template <size_t TestModuleIndex> template <size_t TestModuleIndex>
......
...@@ -84,7 +84,6 @@ ...@@ -84,7 +84,6 @@
1340 WIN : dEQP-EGL.functional.render.multi_context.gles2_gles3.rgba5551_window = FAIL 1340 WIN : dEQP-EGL.functional.render.multi_context.gles2_gles3.rgba5551_window = FAIL
1340 WIN : dEQP-EGL.functional.render.multi_context.gles2_gles3.rgba5551_pbuffer = FAIL 1340 WIN : dEQP-EGL.functional.render.multi_context.gles2_gles3.rgba5551_pbuffer = FAIL
1340 WIN : dEQP-EGL.functional.negative_api.choose_config = SKIP 1340 WIN : dEQP-EGL.functional.negative_api.choose_config = SKIP
1340 WIN : dEQP-EGL.functional.negative_api.get_display = FAIL
1340 WIN : dEQP-EGL.functional.negative_api.surface_attrib = SKIP 1340 WIN : dEQP-EGL.functional.negative_api.surface_attrib = SKIP
1340 WIN : dEQP-EGL.functional.negative_api.swap_interval = FAIL 1340 WIN : dEQP-EGL.functional.negative_api.swap_interval = FAIL
2382 WIN : dEQP-EGL.functional.native_color_mapping.native_window.* = SKIP 2382 WIN : dEQP-EGL.functional.native_color_mapping.native_window.* = SKIP
...@@ -142,7 +141,6 @@ ...@@ -142,7 +141,6 @@
2546 LINUX : dEQP-EGL.functional.query_surface.simple.pixmap.rgba8888_depth_stencil = SKIP 2546 LINUX : dEQP-EGL.functional.query_surface.simple.pixmap.rgba8888_depth_stencil = SKIP
2546 LINUX : dEQP-EGL.functional.query_surface.simple.pixmap.rgba8888_no_depth_no_stencil = SKIP 2546 LINUX : dEQP-EGL.functional.query_surface.simple.pixmap.rgba8888_no_depth_no_stencil = SKIP
2546 LINUX : dEQP-EGL.functional.render.multi_context.* = SKIP 2546 LINUX : dEQP-EGL.functional.render.multi_context.* = SKIP
2546 LINUX : dEQP-EGL.functional.render.multi_context.gles2.rgba8888_pixmap = SKIP
2546 LINUX : dEQP-EGL.functional.render.single_context.gles2.rgba8888_pixmap = SKIP 2546 LINUX : dEQP-EGL.functional.render.single_context.gles2.rgba8888_pixmap = SKIP
2546 LINUX : dEQP-EGL.functional.render.single_context.gles3.rgba8888_pixmap = SKIP 2546 LINUX : dEQP-EGL.functional.render.single_context.gles3.rgba8888_pixmap = SKIP
2546 LINUX : dEQP-EGL.functional.thread_cleanup.* = SKIP 2546 LINUX : dEQP-EGL.functional.thread_cleanup.* = SKIP
...@@ -220,13 +218,10 @@ ...@@ -220,13 +218,10 @@
// ES 1 tests // ES 1 tests
2306 WIN : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL 2306 WIN : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL
2306 WIN : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL 2306 WIN : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL
2306 WIN : dEQP-EGL.functional.color_clears.multi_thread.gles1* = FAIL
2306 MAC : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL 2306 MAC : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL
2306 MAC : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL 2306 MAC : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL
2306 MAC : dEQP-EGL.functional.color_clears.multi_thread.gles1* = FAIL
2306 LINUX : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL 2306 LINUX : dEQP-EGL.functional.color_clears.single_context.gles1* = FAIL
2306 LINUX : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL 2306 LINUX : dEQP-EGL.functional.color_clears.multi_context.gles1* = FAIL
2306 LINUX : dEQP-EGL.functional.color_clears.multi_thread.gles1* = FAIL
// Tests failing since the Jan 2018 roll of dEQP // Tests failing since the Jan 2018 roll of dEQP
2341 : dEQP-EGL.functional.swap_buffers.* = SKIP 2341 : dEQP-EGL.functional.swap_buffers.* = SKIP
......
...@@ -32,10 +32,6 @@ ...@@ -32,10 +32,6 @@
// Skip these tests due to timeouts // Skip these tests due to timeouts
1034 : dEQP-GLES2.functional.flush_finish.* = SKIP 1034 : dEQP-GLES2.functional.flush_finish.* = SKIP
// Don't run these tests for faster turnover
998 : dEQP-GLES2.performance.* = SKIP
998 : dEQP-GLES2.stress.* = SKIP
// Failures related to not supporting separate depth/stencil masks on D3D11. // Failures related to not supporting separate depth/stencil masks on D3D11.
1655 D3D11 : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil_depth_funcs.stencil_* = FAIL 1655 D3D11 : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil_depth_funcs.stencil_* = FAIL
1655 D3D11 : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil_ops.* = FAIL 1655 D3D11 : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil_ops.* = FAIL
...@@ -292,12 +288,19 @@ ...@@ -292,12 +288,19 @@
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL 3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL 3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL
3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL 3243 VULKAN : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL // D3D11 AMD already covered by Line 148
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL 3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_nearest = FAIL 3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL 3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_nearest = FAIL
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL 3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL
3243 D3D11 : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL 3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL
3243 D3D11 INTEL : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_linear = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_nearest = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.projected.linear_linear = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_nearest = FAIL
3243 D3D11 NVIDIA : dEQP-GLES2.functional.texture.mipmap.cube.bias.linear_linear = FAIL
// Fail with very tiny pixel differences // Fail with very tiny pixel differences
3240 VULKAN : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_nearest_clamp = FAIL 3240 VULKAN : dEQP-GLES2.functional.texture.vertex.cube.filtering.linear_mipmap_linear_nearest_clamp = FAIL
......
...@@ -51,18 +51,6 @@ ...@@ -51,18 +51,6 @@
1442 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP 1442 : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.type.vertex_fragment.struct.* = SKIP
1442 : dEQP-GLES31.functional.image_load_store.* = SKIP 1442 : dEQP-GLES31.functional.image_load_store.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP
// TODO(xinghua.cao@intel.com): FAIL expectation instead of SKIP should be sufficient for OpenGL, but the
// test expectations parser doesn't support having FAIL for GL and SKIP for D3D with the same test filter.
1729 D3D11 : dEQP-GLES31.functional.atomic_counter.* = SKIP
1951 D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = SKIP
1951 D3D11 : dEQP-GLES31.functional.shaders.opaque_type_indexing.ssbo.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.program_interface_query.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.synchronization.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.layout_binding.image.* = SKIP
// This case is skipped since it uses atomic counter builtin functions which haven't been implemented.
1729 D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = SKIP
// D3D11 Failing Tests // D3D11 Failing Tests
// Below cases are failed due to binding multi-UAVs to a single buffer is not supported in D3D backend. // Below cases are failed due to binding multi-UAVs to a single buffer is not supported in D3D backend.
...@@ -605,3 +593,16 @@ ...@@ -605,3 +593,16 @@
1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_shared_memory_size_limit = FAIL 1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_shared_memory_size_limit = FAIL
1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_shared_memory_size_limit = FAIL 1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_shared_memory_size_limit = FAIL
1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_shared_memory_size_limit = FAIL 1951 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_shared_memory_size_limit = FAIL
1442 D3D11 : dEQP-GLES31.functional.stencil_texturing.* = SKIP
// TODO(xinghua.cao@intel.com): FAIL expectation instead of SKIP should be sufficient for OpenGL, but the
// test expectations parser doesn't support having FAIL for GL and SKIP for D3D with the same test filter.
1729 D3D11 : dEQP-GLES31.functional.atomic_counter.* = SKIP
1951 D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = SKIP
1951 D3D11 : dEQP-GLES31.functional.shaders.opaque_type_indexing.ssbo.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.program_interface_query.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.synchronization.* = SKIP
1442 D3D11 : dEQP-GLES31.functional.layout_binding.image.* = SKIP
// This case is skipped since it uses atomic counter builtin functions which haven't been implemented.
1729 D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = SKIP
...@@ -30,8 +30,6 @@ ...@@ -30,8 +30,6 @@
// 91531 NEXUS5X GLES : conformance_more_* = SKIP // 91531 NEXUS5X GLES : conformance_more_* = SKIP
// Don't run these tests for faster turnover // Don't run these tests for faster turnover
998 : dEQP-GLES3.performance.* = SKIP
998 : dEQP-GLES3.stress.* = SKIP
1101 : dEQP-GLES3.functional.flush_finish.* = SKIP 1101 : dEQP-GLES3.functional.flush_finish.* = SKIP
// Figure out why this caused this regression in Chrome: // Figure out why this caused this regression in Chrome:
...@@ -121,10 +119,6 @@ ...@@ -121,10 +119,6 @@
1095 LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.* = FAIL 1095 LINUX : dEQP-GLES3.functional.texture.mipmap.2d.projected.* = FAIL
// Windows only failure // Windows only failure
1092 WIN D3D11 : dEQP-GLES3.functional.shaders.texture_functions.textureoffset.sampler3d_fixed_fragment = FAIL
1092 WIN D3D11 : dEQP-GLES3.functional.shaders.texture_functions.textureoffset.sampler3d_float_fragment = FAIL
1092 WIN D3D11 : dEQP-GLES3.functional.shaders.texture_functions.textureprojoffset.sampler3d_fixed_fragment = FAIL
1092 WIN D3D11 : dEQP-GLES3.functional.shaders.texture_functions.textureprojoffset.sampler3d_float_fragment = FAIL
1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_depth_funcs.stencil_* = FAIL 1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_depth_funcs.stencil_* = FAIL
1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_ops.* = FAIL 1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.stencil_ops.* = FAIL
1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.write_mask.* = FAIL 1096 WIN D3D11 : dEQP-GLES3.functional.fragment_ops.depth_stencil.write_mask.* = FAIL
...@@ -274,12 +268,6 @@ ...@@ -274,12 +268,6 @@
1323 LINUX OPENGL : dEQP-GLES3.functional.fbo.depth.depth_write_clamp.depth_component32f = FAIL 1323 LINUX OPENGL : dEQP-GLES3.functional.fbo.depth.depth_write_clamp.depth_component32f = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.fbo.depth.depth_write_clamp.depth32f_stencil8 = FAIL 1323 LINUX OPENGL : dEQP-GLES3.functional.fbo.depth.depth_write_clamp.depth32f_stencil8 = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.rasterization.fbo.rbo_multisample_max.primitives.points = FAIL 1323 LINUX OPENGL : dEQP-GLES3.functional.rasterization.fbo.rbo_multisample_max.primitives.points = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_linear_clamp = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_linear_mirror = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.linear_linear_repeat = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_linear_clamp = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_linear_mirror = FAIL
1323 LINUX OPENGL : dEQP-GLES3.functional.texture.mipmap.2d.projected.nearest_linear_repeat = FAIL
// While loops with 'continue' seem flaky on Linux. (Possibly all GL renderers) // While loops with 'continue' seem flaky on Linux. (Possibly all GL renderers)
1324 LINUX OPENGL : dEQP-GLES3.functional.shaders.loops.while_constant_iterations.conditional_continue_vertex = FAIL 1324 LINUX OPENGL : dEQP-GLES3.functional.shaders.loops.while_constant_iterations.conditional_continue_vertex = FAIL
...@@ -700,9 +688,6 @@ ...@@ -700,9 +688,6 @@
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_samples_get* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_samples_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.min_program_texel_offset_get* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.integers.min_program_texel_offset_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.compressed_texture_formats_get* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.integers.compressed_texture_formats_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_uniform_block_size_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_combined_vertex_uniform_components_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers.max_combined_fragment_uniform_components_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.indexed.uniform_buffer* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.indexed.uniform_buffer* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_uniform_block_size_get* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_uniform_block_size_get* = FAIL
2950 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_vertex_uniform_components_get* = FAIL 2950 VULKAN : dEQP-GLES3.functional.state_query.integers64.max_combined_vertex_uniform_components_get* = FAIL
......
...@@ -272,12 +272,27 @@ bool GPUTestExpectationsParser::loadTestExpectationsFromFile(const GPUTestConfig ...@@ -272,12 +272,27 @@ bool GPUTestExpectationsParser::loadTestExpectationsFromFile(const GPUTestConfig
return loadTestExpectations(config, data); return loadTestExpectations(config, data);
} }
int32_t GPUTestExpectationsParser::getTestExpectation(const std::string &testName) const int32_t GPUTestExpectationsParser::getTestExpectation(const std::string &testName)
{ {
size_t maxExpectationLen = 0;
GPUTestExpectationEntry *foundEntry = nullptr;
for (size_t i = 0; i < mEntries.size(); ++i) for (size_t i = 0; i < mEntries.size(); ++i)
{ {
if (NamesMatching(mEntries[i].mTestName, testName)) if (NamesMatching(mEntries[i].testName, testName))
return mEntries[i].mTestExpectation; {
size_t expectationLen = mEntries[i].testName.length();
// The longest/most specific matching expectation overrides any others.
if (expectationLen > maxExpectationLen)
{
maxExpectationLen = expectationLen;
foundEntry = &mEntries[i];
}
}
}
if (foundEntry != nullptr)
{
foundEntry->used = true;
return foundEntry->testExpectation;
} }
return kGpuTestPass; return kGpuTestPass;
} }
...@@ -287,6 +302,20 @@ const std::vector<std::string> &GPUTestExpectationsParser::getErrorMessages() co ...@@ -287,6 +302,20 @@ const std::vector<std::string> &GPUTestExpectationsParser::getErrorMessages() co
return mErrorMessages; return mErrorMessages;
} }
std::vector<std::string> GPUTestExpectationsParser::getUnusedExpectationsMessages() const
{
std::vector<std::string> messages;
std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry> unusedExpectations =
getUnusedExpectations();
for (size_t i = 0; i < unusedExpectations.size(); ++i)
{
std::string message =
"Line " + ToString(unusedExpectations[i].lineNumber) + ": expectation was unused.";
messages.push_back(message);
}
return messages;
}
bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config, bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config,
const std::string &lineData, const std::string &lineData,
size_t lineNumber) size_t lineNumber)
...@@ -295,7 +324,8 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config, ...@@ -295,7 +324,8 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config,
SplitString(lineData, kWhitespaceASCII, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); SplitString(lineData, kWhitespaceASCII, KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
int32_t stage = kLineParserBegin; int32_t stage = kLineParserBegin;
GPUTestExpectationEntry entry; GPUTestExpectationEntry entry;
entry.mLineNumber = lineNumber; entry.lineNumber = lineNumber;
entry.used = false;
bool skipLine = false; bool skipLine = false;
for (size_t i = 0; i < tokens.size() && !skipLine; ++i) for (size_t i = 0; i < tokens.size() && !skipLine; ++i)
{ {
...@@ -392,7 +422,7 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config, ...@@ -392,7 +422,7 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config,
} }
else if (stage == kLineParserColon) else if (stage == kLineParserColon)
{ {
entry.mTestName = tokens[i]; entry.testName = tokens[i];
} }
else else
{ {
...@@ -412,13 +442,13 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config, ...@@ -412,13 +442,13 @@ bool GPUTestExpectationsParser::parseLine(const GPUTestConfig &config,
pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber); pushErrorMessage(kErrorMessage[kErrorIllegalEntry], lineNumber);
return false; return false;
} }
if (entry.mTestExpectation != 0) if (entry.testExpectation != 0)
{ {
pushErrorMessage(kErrorMessage[kErrorEntryWithExpectationConflicts], pushErrorMessage(kErrorMessage[kErrorEntryWithExpectationConflicts],
lineNumber); lineNumber);
return false; return false;
} }
entry.mTestExpectation = kTokenData[token].expectation; entry.testExpectation = kTokenData[token].expectation;
if (stage == kLineParserEqual) if (stage == kLineParserEqual)
stage++; stage++;
break; break;
...@@ -472,10 +502,10 @@ bool GPUTestExpectationsParser::detectConflictsBetweenEntries() ...@@ -472,10 +502,10 @@ bool GPUTestExpectationsParser::detectConflictsBetweenEntries()
{ {
for (size_t j = i + 1; j < mEntries.size(); ++j) for (size_t j = i + 1; j < mEntries.size(); ++j)
{ {
if (mEntries[i].mTestName == mEntries[j].mTestName) if (mEntries[i].testName == mEntries[j].testName)
{ {
pushErrorMessage(kErrorMessage[kErrorEntriesOverlap], mEntries[i].mLineNumber, pushErrorMessage(kErrorMessage[kErrorEntriesOverlap], mEntries[i].lineNumber,
mEntries[j].mLineNumber); mEntries[j].lineNumber);
rt = true; rt = true;
} }
} }
...@@ -483,6 +513,20 @@ bool GPUTestExpectationsParser::detectConflictsBetweenEntries() ...@@ -483,6 +513,20 @@ bool GPUTestExpectationsParser::detectConflictsBetweenEntries()
return rt; return rt;
} }
std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry>
GPUTestExpectationsParser::getUnusedExpectations() const
{
std::vector<GPUTestExpectationsParser::GPUTestExpectationEntry> unusedExpectations;
for (size_t i = 0; i < mEntries.size(); ++i)
{
if (!mEntries[i].used)
{
unusedExpectations.push_back(mEntries[i]);
}
}
return unusedExpectations;
}
void GPUTestExpectationsParser::pushErrorMessage(const std::string &message, size_t lineNumber) void GPUTestExpectationsParser::pushErrorMessage(const std::string &message, size_t lineNumber)
{ {
mErrorMessages.push_back("Line " + ToString(lineNumber) + " : " + message.c_str()); mErrorMessages.push_back("Line " + ToString(lineNumber) + " : " + message.c_str());
...@@ -497,7 +541,7 @@ void GPUTestExpectationsParser::pushErrorMessage(const std::string &message, ...@@ -497,7 +541,7 @@ void GPUTestExpectationsParser::pushErrorMessage(const std::string &message,
} }
GPUTestExpectationsParser::GPUTestExpectationEntry::GPUTestExpectationEntry() GPUTestExpectationsParser::GPUTestExpectationEntry::GPUTestExpectationEntry()
: mTestExpectation(0), mLineNumber(0) : testExpectation(0), lineNumber(0)
{} {}
} // namespace angle } // namespace angle
...@@ -42,17 +42,21 @@ class GPUTestExpectationsParser ...@@ -42,17 +42,21 @@ class GPUTestExpectationsParser
// Query error messages from the last LoadTestExpectations() call. // Query error messages from the last LoadTestExpectations() call.
const std::vector<std::string> &getErrorMessages() const; const std::vector<std::string> &getErrorMessages() const;
// Query error messages from any expectations that weren't used before being queried.
std::vector<std::string> getUnusedExpectationsMessages() const;
// Get the test expectation of a given test on a given bot. // Get the test expectation of a given test on a given bot.
int32_t getTestExpectation(const std::string &testName) const; int32_t getTestExpectation(const std::string &testName);
private: private:
struct GPUTestExpectationEntry struct GPUTestExpectationEntry
{ {
GPUTestExpectationEntry(); GPUTestExpectationEntry();
std::string mTestName; std::string testName;
int32_t mTestExpectation; int32_t testExpectation;
size_t mLineNumber; size_t lineNumber;
bool used;
}; };
// Parse a line of text. If we have a valid entry, save it; otherwise, // Parse a line of text. If we have a valid entry, save it; otherwise,
...@@ -69,6 +73,9 @@ class GPUTestExpectationsParser ...@@ -69,6 +73,9 @@ class GPUTestExpectationsParser
// error message. // error message.
bool detectConflictsBetweenEntries(); bool detectConflictsBetweenEntries();
// Query a list of any expectations that were's used before being queried.
std::vector<GPUTestExpectationEntry> getUnusedExpectations() const;
// Save an error message, which can be queried later. // Save an error message, which can be queried later.
void pushErrorMessage(const std::string &message, size_t lineNumber); void pushErrorMessage(const std::string &message, size_t lineNumber);
void pushErrorMessage(const std::string &message, void pushErrorMessage(const std::string &message,
......
...@@ -352,4 +352,73 @@ TEST(GPUTestExpectationsParserTest, GPUTestExpectationsParserComment) ...@@ -352,4 +352,73 @@ TEST(GPUTestExpectationsParserTest, GPUTestExpectationsParserComment)
GPUTestExpectationsParser::kGpuTestPass); GPUTestExpectationsParser::kGpuTestPass);
} }
// A misspelled expectation should not be matched from getTestExpectation, and should lead to an
// unused expectation when later queried.
TEST(GPUTestExpectationsParserTest, GPUTestExpectationsParserMisspelledExpectation)
{
GPUTestConfigTester config;
std::string line =
R"(100 : dEQP-GLES31.functionaal.layout_binding.ubo.* = SKIP)"; // "functionaal"
GPUTestExpectationsParser parser;
EXPECT_TRUE(parser.loadTestExpectations(config, line));
EXPECT_TRUE(parser.getErrorMessages().empty());
// Default behavior is to let missing tests pass
EXPECT_EQ(
parser.getTestExpectation("dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_max"),
GPUTestExpectationsParser::kGpuTestPass);
EXPECT_EQ(parser.getUnusedExpectationsMessages().size(), 1u);
if (parser.getUnusedExpectationsMessages().size() >= 1)
EXPECT_EQ(parser.getUnusedExpectationsMessages()[0], "Line 1: expectation was unused.");
}
// Wild characters that match groups of expectations can be overridden with more specific lines.
// The parse should still compute correctly which lines were used and which were unused.
TEST(GPUTestExpectationsParserTest, GPUTestExpectationsParserOverrideExpectation)
{
GPUTestConfigTester config;
// Fail all layout_binding tests, but skip the layout_binding.ubo subset.
std::string line = R"(100 : dEQP-GLES31.functional.layout_binding.* = FAIL
100 : dEQP-GLES31.functional.layout_binding.ubo.* = SKIP)";
GPUTestExpectationsParser parser;
EXPECT_TRUE(parser.loadTestExpectations(config, line));
EXPECT_TRUE(parser.getErrorMessages().empty());
// Default behavior is to let missing tests pass
EXPECT_EQ(
parser.getTestExpectation("dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_max"),
GPUTestExpectationsParser::kGpuTestSkip);
// The FAIL expectation was unused because it was overridden.
EXPECT_EQ(parser.getUnusedExpectationsMessages().size(), 1u);
if (parser.getUnusedExpectationsMessages().size() >= 1)
EXPECT_EQ(parser.getUnusedExpectationsMessages()[0], "Line 1: expectation was unused.");
// Now try a test that doesn't match the override criteria
EXPECT_EQ(parser.getTestExpectation("dEQP-GLES31.functional.layout_binding.image.test"),
GPUTestExpectationsParser::kGpuTestFail);
EXPECT_TRUE(parser.getUnusedExpectationsMessages().empty());
}
// This test is the same as GPUTestExpectationsParserOverrideExpectation, but verifying the order
// doesn't matter when overriding.
TEST(GPUTestExpectationsParserTest, GPUTestExpectationsParserOverrideExpectationOtherOrder)
{
GPUTestConfigTester config;
// Fail all layout_binding tests, but skip the layout_binding.ubo subset.
std::string line = R"(100 : dEQP-GLES31.functional.layout_binding.ubo.* = SKIP
100 : dEQP-GLES31.functional.layout_binding.* = FAIL)";
GPUTestExpectationsParser parser;
EXPECT_TRUE(parser.loadTestExpectations(config, line));
EXPECT_TRUE(parser.getErrorMessages().empty());
// Default behavior is to let missing tests pass
EXPECT_EQ(
parser.getTestExpectation("dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_max"),
GPUTestExpectationsParser::kGpuTestSkip);
// The FAIL expectation was unused because it was overridden.
EXPECT_EQ(parser.getUnusedExpectationsMessages().size(), 1u);
if (parser.getUnusedExpectationsMessages().size() >= 1)
EXPECT_EQ(parser.getUnusedExpectationsMessages()[0], "Line 2: expectation was unused.");
// Now try a test that doesn't match the override criteria
EXPECT_EQ(parser.getTestExpectation("dEQP-GLES31.functional.layout_binding.image.test"),
GPUTestExpectationsParser::kGpuTestFail);
EXPECT_TRUE(parser.getUnusedExpectationsMessages().empty());
}
} // anonymous namespace } // anonymous namespace
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