Commit 60abae9c authored by Lin Sun's avatar Lin Sun Committed by Commit Bot

Generates GPU driver tags for WebGL expectations

For WebGL conformance test, we can specify some conditions to limit the
test environment that one test case may fail. But these conditions don't
include graphics driver information. By this patch, the WebGL test
framework can generate driver tags based on the vendor and version of
the graphics driver of current system for the expectations file. The
format of driver tag is as below:
crbug.com/123 [ linux mesa_lt_18.0.5 ] abc.html [ Failure ]

When adding or removing driver tags in the expectatioins file, it's also
necessary to modify the list of available driver tags in the header of
webgl_conformance_integration_test.py.

Bug: 957515
Change-Id: I29835cae0b042cd86eb4fa438f60803e371d8d1a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1647464
Commit-Queue: Lin Sun <lin.sun@intel.com>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672596}
parent f654f0fc
...@@ -64,6 +64,22 @@ def GetGpuDeviceId(gpu_info): ...@@ -64,6 +64,22 @@ def GetGpuDeviceId(gpu_info):
return 0 return 0
def GetGpuDriverVendor(gpu_info):
if gpu_info:
primary_gpu = gpu_info.devices[0]
if primary_gpu:
return primary_gpu.driver_vendor
return None
def GetGpuDriverVersion(gpu_info):
if gpu_info:
primary_gpu = gpu_info.devices[0]
if primary_gpu:
return primary_gpu.driver_version
return None
def GetANGLERenderer(gpu_info): def GetANGLERenderer(gpu_info):
if gpu_info and gpu_info.aux_attributes: if gpu_info and gpu_info.aux_attributes:
gl_renderer = gpu_info.aux_attributes.get('gl_renderer') gl_renderer = gpu_info.aux_attributes.get('gl_renderer')
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
# tags: [ intel amd-0x699f nvidia-0x1cb3 amd-0x6613 amd # tags: [ intel amd-0x699f nvidia-0x1cb3 amd-0x6613 amd
# qualcomm nvidia-0xfe9 nvidia nvidia-0xf02 intel-0xa2e ] # qualcomm nvidia-0xfe9 nvidia nvidia-0xf02 intel-0xa2e ]
# tags: [ debug ] # tags: [ debug ]
# tags: [ intel_lt_25.20.100.6444 mesa_lt_17.3.9 mesa_lt_17.1.6 ]
# =================================== # ===================================
...@@ -197,8 +198,8 @@ crbug.com/614418 [ d3d11 win intel ] deqp/functional/gles3/textureformat/unsized ...@@ -197,8 +198,8 @@ crbug.com/614418 [ d3d11 win intel ] deqp/functional/gles3/textureformat/unsized
# Case no-over-optimization-on-uniform-array-08 always fail if run # Case no-over-optimization-on-uniform-array-08 always fail if run
# case gl-min-uniforms first. # case gl-min-uniforms first.
# Temporarily skip these two cases now. # Temporarily skip these two cases now.
crbug.com/953243 [ opengl win passthrough intel ] conformance/limits/gl-min-uniforms.html [ Skip ] crbug.com/953243 [ opengl win passthrough intel intel_lt_25.20.100.6444 ] conformance/limits/gl-min-uniforms.html [ Skip ]
crbug.com/953243 [ opengl win passthrough intel ] conformance/uniforms/no-over-optimization-on-uniform-array-08.html [ Skip ] crbug.com/953243 [ opengl win passthrough intel intel_lt_25.20.100.6444 ] conformance/uniforms/no-over-optimization-on-uniform-array-08.html [ Skip ]
# This is an OpenGL driver bug on Intel platform and it is fixed in # This is an OpenGL driver bug on Intel platform and it is fixed in
# Intel Driver 25.20.100.6444. # Intel Driver 25.20.100.6444.
...@@ -206,8 +207,8 @@ crbug.com/953243 [ opengl win passthrough intel ] conformance/uniforms/no-over-o ...@@ -206,8 +207,8 @@ crbug.com/953243 [ opengl win passthrough intel ] conformance/uniforms/no-over-o
# case biuDepthRange_001_to_002 first. # case biuDepthRange_001_to_002 first.
# Temporarily skip these two cases now because this issue blocks # Temporarily skip these two cases now because this issue blocks
# WEBGL_video_texture implementation. # WEBGL_video_texture implementation.
crbug.com/907195 [ opengl win passthrough intel ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ] crbug.com/907195 [ opengl win passthrough intel intel_lt_25.20.100.6444 ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ]
crbug.com/907195 [ opengl win passthrough intel ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ] crbug.com/907195 [ opengl win passthrough intel intel_lt_25.20.100.6444 ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ]
# It's unfortunate that these suppressions need to be so broad, but it # It's unfortunate that these suppressions need to be so broad, but it
# looks like the D3D11 device can be lost spontaneously on this # looks like the D3D11 device can be lost spontaneously on this
...@@ -571,13 +572,13 @@ crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] deqp/functional/gles3/fbocomplet ...@@ -571,13 +572,13 @@ crbug.com/703779 [ opengl linux nvidia-0x1cb3 ] deqp/functional/gles3/fbocomplet
crbug.com/950552 [ linux intel ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ] crbug.com/950552 [ linux intel ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
crbug.com/950552 [ linux intel ] conformance2/textures/misc/tex-3d-size-limit.html [ Failure ] crbug.com/950552 [ linux intel ] conformance2/textures/misc/tex-3d-size-limit.html [ Failure ]
# Already fixed with Mesa 17.2.3 crbug.com/680675 [ linux intel mesa_lt_17.1.6 ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ]
crbug.com/905011 [ linux intel ] conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html [ Failure ] crbug.com/905011 [ linux intel mesa_lt_17.3.9 ] conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html [ Failure ]
crbug.com/666384 [ linux intel ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ Failure ] crbug.com/666384 [ linux intel mesa_lt_17.3.9 ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ Failure ]
crbug.com/666384 [ linux intel ] conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html [ Failure ] crbug.com/666384 [ linux intel mesa_lt_17.3.9 ] conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html [ Failure ]
crbug.com/905011 [ linux intel opengl passthrough ] conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html [ Failure ]
# Already fixed with Mesa 17.1.6 crbug.com/666384 [ linux intel opengl passthrough ] deqp/functional/gles3/shadertexturefunction/texturesize.html [ Failure ]
crbug.com/680675 [ linux intel ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] crbug.com/666384 [ linux intel opengl passthrough ] conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html [ Failure ]
# Linux AMD only. # Linux AMD only.
# It looks like AMD shader compiler rejects many valid ES3 semantics. # It looks like AMD shader compiler rejects many valid ES3 semantics.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
# tags: [ d3d11 d3d9 no-angle opengl opengles vulkan ] # tags: [ d3d11 d3d9 no-angle opengl opengles vulkan ]
# tags: [ no-passthrough passthrough ] # tags: [ no-passthrough passthrough ]
# tags: [ webgl-version-1 ] # tags: [ webgl-version-1 ]
# tags: [ intel_lt_25.20.100.6444 mesa_lt_17.1.6 ]
# =================================== # ===================================
...@@ -174,8 +175,8 @@ crbug.com/929009 [ win intel ] conformance/glsl/misc/shader-with-non-reserved-wo ...@@ -174,8 +175,8 @@ crbug.com/929009 [ win intel ] conformance/glsl/misc/shader-with-non-reserved-wo
# case biuDepthRange_001_to_002 first. # case biuDepthRange_001_to_002 first.
# Temporarily skip these two cases now because this issue blocks # Temporarily skip these two cases now because this issue blocks
# WEBGL_video_texture implementation. # WEBGL_video_texture implementation.
crbug.com/907195 [ win intel opengl passthrough ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ] crbug.com/907195 [ win intel opengl passthrough intel_lt_25.20.100.6444 ] conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html [ Skip ]
crbug.com/907195 [ win intel opengl passthrough ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ] crbug.com/907195 [ win intel opengl passthrough intel_lt_25.20.100.6444 ] conformance/uniforms/no-over-optimization-on-uniform-array-09.html [ Skip ]
# Win7 / Intel failures # Win7 / Intel failures
[ win7 intel no-passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ] [ win7 intel no-passthrough ] conformance/textures/misc/copy-tex-image-and-sub-image-2d.html [ Failure ]
...@@ -379,7 +380,7 @@ crbug.com/948218 [ mac debug nvidia-0xfe9 ] conformance/glsl/misc/shader-with-no ...@@ -379,7 +380,7 @@ crbug.com/948218 [ mac debug nvidia-0xfe9 ] conformance/glsl/misc/shader-with-no
#################### ####################
# Already fixed with Mesa 17.1.6 # Already fixed with Mesa 17.1.6
crbug.com/680675 [ linux intel ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] crbug.com/680675 [ linux intel mesa_lt_17.1.6 ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ]
# NVIDIA # NVIDIA
crbug.com/524144 [ linux nvidia no-passthrough ] conformance/extensions/oes-element-index-uint.html [ RetryOnFailure ] crbug.com/524144 [ linux nvidia no-passthrough ] conformance/extensions/oes-element-index-uint.html [ RetryOnFailure ]
......
...@@ -74,6 +74,100 @@ def _IsCollision(s1, s2): ...@@ -74,6 +74,100 @@ def _IsCollision(s1, s2):
return True return True
def _IsDriverTagDuplicated(s1, s2, test_class):
if not test_class:
return False
def classify_tags(tags):
driver_tag = None
other_tags = []
for tag in tags:
if test_class.MatchDriverTag(tag):
assert not driver_tag
driver_tag = tag
else:
other_tags.append(tag)
return driver_tag, other_tags
driver_tag1, other_tags1 = classify_tags(s1)
driver_tag2, other_tags2 = classify_tags(s2)
if not driver_tag1 and not driver_tag2:
return False
if not _IsCollision(other_tags1, other_tags2):
return False
if driver_tag1 == driver_tag2 or (not driver_tag1 or not driver_tag2):
return True
match = test_class.MatchDriverTag(driver_tag1)
tag1 = (match.group(1), match.group(2), match.group(3))
match = test_class.MatchDriverTag(driver_tag2)
tag2 = (match.group(1), match.group(2), match.group(3))
if not tag1[0] == tag2[0]:
return False
operation1, version1 = tag1[1:]
operation2, version2 = tag2[1:]
if operation1 == 'ne':
return not (operation2 == 'eq' and version1 == version2)
elif operation2 == 'ne':
return not (operation1 == 'eq' and version1 == version2)
elif operation1 == 'eq':
return test_class.EvaluateVersionComparison(
version1, operation2, version2)
elif operation2 == 'eq':
return test_class.EvaluateVersionComparison(
version2, operation1, version1)
if operation1 == 'ge' or operation1 == 'gt':
if operation2 == 'ge' or operation2 == 'gt':
return True
elif operation1 == 'le' or operation1 == 'lt':
if operation2 == 'le' or operation2 == 'lt':
return True
if operation1 == 'ge':
if operation2 == 'le':
return not test_class.EvaluateVersionComparison(version1, 'gt', version2)
elif operation2 == 'lt':
return not test_class.EvaluateVersionComparison(version1, 'ge', version2)
elif operation1 == 'gt':
return not test_class.EvaluateVersionComparison(version1, 'ge', version2)
elif operation1 == 'le':
if operation2 == 'ge':
return not test_class.EvaluateVersionComparison(version1, 'lt', version2)
elif operation2 == 'gt':
return not test_class.EvaluateVersionComparison(version1, 'le', version2)
elif operation1 == 'lt':
return not test_class.EvaluateVersionComparison(version1, 'le', version2)
else:
assert False
def _ExtractUnitTestTestExpectations(file_name):
file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'..', 'unittest_data', 'test_expectations', file_name)
test_expectations_list = []
with open(file_name, 'r') as test_data:
test_expectations = ''
reach_end = False
while not reach_end:
line = test_data.readline()
if line:
line = line.strip()
if line:
test_expectations += line + '\n'
continue
else:
reach_end = True
if test_expectations:
test_expectations_list.append(test_expectations)
test_expectations = ''
assert test_expectations_list
return test_expectations_list
def _MapGpuDevicesToVendors(tag_sets): def _MapGpuDevicesToVendors(tag_sets):
for tag_set in tag_sets: for tag_set in tag_sets:
if any(gpu in tag_set for gpu in GPU_CONDITIONS): if any(gpu in tag_set for gpu in GPU_CONDITIONS):
...@@ -110,7 +204,8 @@ def CheckTestExpectationsAreForExistingTests( ...@@ -110,7 +204,8 @@ def CheckTestExpectationsAreForExistingTests(
_trie = _trie[l] _trie = _trie[l]
def CheckTestExpectationGlobsForCollision(expectations, file_name): def CheckTestExpectationGlobsForCollision(
expectations, file_name, test_class=None):
"""This function looks for collisions between test expectations with patterns """This function looks for collisions between test expectations with patterns
that match with test expectation patterns that are globs. A test expectation that match with test expectation patterns that are globs. A test expectation
collides with another if its pattern matches with another's glob and if its collides with another if its pattern matches with another's glob and if its
...@@ -159,7 +254,9 @@ def CheckTestExpectationGlobsForCollision(expectations, file_name): ...@@ -159,7 +254,9 @@ def CheckTestExpectationGlobsForCollision(expectations, file_name):
for possible_collision in globs_to_match: for possible_collision in globs_to_match:
reason = _ConflictLeaksRegression(possible_collision, match) reason = _ConflictLeaksRegression(possible_collision, match)
if (reason and if (reason and
_IsCollision(possible_collision.tags, match.tags)): (_IsCollision(possible_collision.tags, match.tags)
or _IsDriverTagDuplicated(
possible_collision.tags, match.tags, test_class))):
if not conflicts_found: if not conflicts_found:
error_msg += ('\n\nFound conflicts for pattern %s in %s:\n' % error_msg += ('\n\nFound conflicts for pattern %s in %s:\n' %
(glob, file_name)) (glob, file_name))
...@@ -169,7 +266,8 @@ def CheckTestExpectationGlobsForCollision(expectations, file_name): ...@@ -169,7 +266,8 @@ def CheckTestExpectationGlobsForCollision(expectations, file_name):
assert not master_conflicts_found, error_msg assert not master_conflicts_found, error_msg
def CheckTestExpectationPatternsForCollision(expectations, file_name): def CheckTestExpectationPatternsForCollision(
expectations, file_name, test_class=None):
"""This function makes sure that any test expectations that have the same """This function makes sure that any test expectations that have the same
pattern do not collide with each other. They collide when one expectation's pattern do not collide with each other. They collide when one expectation's
tags are a subset of the other expectation's tags. If the expectation with tags are a subset of the other expectation's tags. If the expectation with
...@@ -191,7 +289,8 @@ def CheckTestExpectationPatternsForCollision(expectations, file_name): ...@@ -191,7 +289,8 @@ def CheckTestExpectationPatternsForCollision(expectations, file_name):
for pattern, exps in tests_to_exps.items(): for pattern, exps in tests_to_exps.items():
conflicts_found = False conflicts_found = False
for e1, e2 in itertools.combinations(exps, 2): for e1, e2 in itertools.combinations(exps, 2):
if _IsCollision(e1.tags, e2.tags) or _IsCollision(e2.tags, e1.tags): if (_IsCollision(e1.tags, e2.tags) or _IsCollision(e2.tags, e1.tags)
or _IsDriverTagDuplicated(e1.tags, e2.tags, test_class)):
if not conflicts_found: if not conflicts_found:
error_msg += ('\n\nFound conflicts for test %s in %s:\n' % error_msg += ('\n\nFound conflicts for test %s in %s:\n' %
(pattern, file_name)) (pattern, file_name))
...@@ -293,8 +392,78 @@ class GpuTestExpectationsValidation(unittest.TestCase): ...@@ -293,8 +392,78 @@ class GpuTestExpectationsValidation(unittest.TestCase):
pixel_integration_test.PixelIntegrationTest, pixel_integration_test.PixelIntegrationTest,
gpu_helper.GetMockArgs(), pixel_test_names) gpu_helper.GetMockArgs(), pixel_test_names)
def testWebglTestExpectationsForDriverTags(self):
webgl_conformance_test_class = (
webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
expectations_driver_tags = set()
for i in range(1, 3):
_ = list(webgl_conformance_test_class.GenerateGpuTests(
gpu_helper.GetMockArgs(webgl_version=('%d.0.0' % i))))
with open(webgl_conformance_test_class.ExpectationsFiles()[0], 'r') as f:
parser = expectations_parser.TaggedTestListParser(f.read())
driver_tag_set = set()
for tag_set in parser.tag_sets:
if webgl_conformance_test_class.MatchDriverTag(list(tag_set)[0]):
for tag in tag_set:
assert webgl_conformance_test_class.MatchDriverTag(tag)
assert not driver_tag_set
driver_tag_set = tag_set
else:
for tag in tag_set:
assert not webgl_conformance_test_class.MatchDriverTag(tag)
expectations_driver_tags |= driver_tag_set
self.assertEqual(
webgl_conformance_test_class.ExpectationsDriverTags(),
expectations_driver_tags)
class TestGpuTestExpectationsValidators(unittest.TestCase): class TestGpuTestExpectationsValidators(unittest.TestCase):
def testCollisionInTestExpectationsWithGpuDriverTags(self):
webgl_conformance_test_class = (
webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
failed_test_expectations = _ExtractUnitTestTestExpectations(
'failed_test_expectations_with_driver_tags.txt')
for test_expectations in failed_test_expectations:
with self.assertRaises(AssertionError):
CheckTestExpectationPatternsForCollision(
test_expectations, 'test.txt', webgl_conformance_test_class)
def testNoCollisionInTestExpectationsWithGpuDriverTags(self):
webgl_conformance_test_class = (
webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
passed_test_expectations = _ExtractUnitTestTestExpectations(
'passed_test_expectations_with_driver_tags.txt')
for test_expectations in passed_test_expectations:
CheckTestExpectationPatternsForCollision(
test_expectations, 'test.txt', webgl_conformance_test_class)
def testCollisionWithGlobsWithGpuDriverTags(self):
webgl_conformance_test_class = (
webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
failed_test_expectations = _ExtractUnitTestTestExpectations(
'failed_test_expectations_with_driver_tags.txt')
for test_expectations in failed_test_expectations:
test_expectations = test_expectations.replace(
'abc.html [ Failure ]', 'a/b/c/* [ Failure ]')
test_expectations = test_expectations.replace(
'abc.html [ RetryOnFailure ]', 'a/b/c/abc.html [ RetryOnFailure ]')
with self.assertRaises(AssertionError):
CheckTestExpectationGlobsForCollision(
test_expectations, 'test.txt', webgl_conformance_test_class)
def testNoCollisionWithGlobsWithGpuDriverTags(self):
webgl_conformance_test_class = (
webgl_conformance_integration_test.WebGLConformanceIntegrationTest)
passed_test_expectations = _ExtractUnitTestTestExpectations(
'passed_test_expectations_with_driver_tags.txt')
for test_expectations in passed_test_expectations:
test_expectations = test_expectations.replace(
'abc.html [ Failure ]', 'a/b/c/* [ Failure ]')
test_expectations = test_expectations.replace(
'abc.html [ RetryOnFailure ]', 'a/b/c/abc.html [ RetryOnFailure ]')
CheckTestExpectationGlobsForCollision(
test_expectations, 'test.txt', webgl_conformance_test_class)
def testCollisionInTestExpectationsWithSpecifcAndGenericOsTags(self): def testCollisionInTestExpectationsWithSpecifcAndGenericOsTags(self):
test_expectations = '''# tags: [ mac win linux xp ] test_expectations = '''# tags: [ mac win linux xp ]
# tags: [ intel amd nvidia ] # tags: [ intel amd nvidia ]
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import logging import logging
import os import os
import re
import sys import sys
from gpu_tests import gpu_helper from gpu_tests import gpu_helper
...@@ -11,6 +12,17 @@ from gpu_tests import gpu_integration_test ...@@ -11,6 +12,17 @@ from gpu_tests import gpu_integration_test
from gpu_tests import path_util from gpu_tests import path_util
from gpu_tests import webgl_test_util from gpu_tests import webgl_test_util
# This set must be the union of the driver tags used in WebGL and WebGL2
# expectations files.
EXPECTATIONS_DRIVER_TAGS = frozenset([
'intel_lt_25.20.100.6444',
'mesa_lt_17.3.9',
'mesa_lt_17.1.6'
])
# Driver tag format: VENDOR_OPERATION_VERSION
DRIVER_TAG_MATCHER = re.compile(r'^([a-z\d]+)_(eq|ne|ge|gt|le|lt)_([a-z\d\.]+)$')
conformance_harness_script = r""" conformance_harness_script = r"""
var testHarness = {}; var testHarness = {};
testHarness._allTestSucceeded = true; testHarness._allTestSucceeded = true;
...@@ -461,8 +473,79 @@ class WebGLConformanceIntegrationTest(gpu_integration_test.GpuIntegrationTest): ...@@ -461,8 +473,79 @@ class WebGLConformanceIntegrationTest(gpu_integration_test.GpuIntegrationTest):
tags.extend( tags.extend(
[['no-asan', 'asan'][cls._is_asan], [['no-asan', 'asan'][cls._is_asan],
'webgl-version-%d' % cls._webgl_version]) 'webgl-version-%d' % cls._webgl_version])
if EXPECTATIONS_DRIVER_TAGS:
system_info = browser.GetSystemInfo()
if system_info:
gpu_info = system_info.gpu
driver_vendor = gpu_helper.GetGpuDriverVendor(gpu_info)
driver_version = gpu_helper.GetGpuDriverVersion(gpu_info)
if driver_vendor and driver_version:
driver_vendor = driver_vendor.lower()
driver_version = driver_version.lower()
# Extract the substring before first space/dash/underscore
matcher = re.compile(r'^([a-z\d]+)([\s\-_]+[a-z\d]+)+$')
match = matcher.match(driver_vendor)
if match:
driver_vendor = match.group(1)
for tag in EXPECTATIONS_DRIVER_TAGS:
match = cls.MatchDriverTag(tag)
assert match
if (driver_vendor == match.group(1) and
cls.EvaluateVersionComparison(
driver_version, match.group(2), match.group(3))):
tags.append(tag)
return tags return tags
@classmethod
def MatchDriverTag(cls, tag):
return DRIVER_TAG_MATCHER.match(tag.lower())
@classmethod
def EvaluateVersionComparison(cls, version1, operation, version2):
def parse_version(ver):
if ver.isdigit():
return int(ver), ''
for i in range(0, len(ver)):
if not ver[i].isdigit():
return int(ver[:i]) if i > 0 else 0, ver[i:]
ver_list1 = version1.split('.')
ver_list2 = version2.split('.')
for i in range(0, max(len(ver_list1), len(ver_list2))):
ver1 = ver_list1[i] if i < len(ver_list1) else '0'
ver2 = ver_list2[i] if i < len(ver_list2) else '0'
num1, suffix1 = parse_version(ver1)
num2, suffix2 = parse_version(ver2)
if not num1 == num2:
diff = num1 - num2
elif suffix1 == suffix2:
continue
elif suffix1 > suffix2:
diff = 1
else:
diff = -1
if operation == 'eq':
return False
elif operation == 'ne':
return True
elif operation == 'ge' or operation == 'gt':
return diff > 0
elif operation == 'le' or operation == 'lt':
return diff < 0
raise Exception('Invalid operation: ' + operation)
return operation == 'eq' or operation == 'ge' or operation == 'le'
@classmethod
def ExpectationsDriverTags(cls):
return EXPECTATIONS_DRIVER_TAGS
@classmethod @classmethod
def ExpectationsFiles(cls): def ExpectationsFiles(cls):
assert cls._webgl_version == 1 or cls._webgl_version == 2 assert cls._webgl_version == 1 or cls._webgl_version == 2
......
# tags: [ linux ]
# tags: [ mesa_ne_18.1 ]
crbug.com/123 [ linux ] abc.html [ Failure ]
crbug.com/123 [ linux mesa_ne_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_ne_18.2 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ne_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_eq_18.2 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_eq_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_gt_18.1 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_ge_18.1 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_lt_18.1 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_le_18.1 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_gt_18.0 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.0 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_ge_18.1 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_lt_18.2 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_lt_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_le_18.1 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_gt_18.0 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.0 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_ge_18.0 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.0 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_lt_18.2 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_lt_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_le_18.2 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_le_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_le_18.1 mesa_gt_18.0 ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.0 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_le_18.1 mesa_ge_18.1 ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_le_18.1 mesa_le_18.2 ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_le_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_gt_18.1 mesa_gt_18.2 ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_gt_18.1 mesa_ge_18.1 ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ge_18.1 mesa_ge_18.2 ]
crbug.com/123 [ mesa_ge_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ linux win ]
# tags: [ mesa_eq_18.1 ]
crbug.com/123 [ linux mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ win mesa_eq_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_ne_18.1 mesa_eq_18.1 ]
crbug.com/123 [ mesa_ne_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_gt_18.1 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_ge_18.2 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_lt_18.1 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_eq_18.1 mesa_le_18.0 ]
crbug.com/123 [ mesa_eq_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_le_18.0 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_gt_18.1 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_lt_18.1 mesa_ge_18.2 ]
crbug.com/123 [ mesa_lt_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.2 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_le_18.1 mesa_gt_18.1 ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_gt_18.1 ] abc.html [ RetryOnFailure ]
# tags: [ mesa_le_18.1 mesa_ge_18.2 ]
crbug.com/123 [ mesa_le_18.1 ] abc.html [ Failure ]
crbug.com/123 [ mesa_ge_18.2 ] abc.html [ RetryOnFailure ]
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