@@ -52,19 +52,27 @@ def is_asan(build_dir):
5252
5353
5454def run_cmd (
55- cmd , forbidden_output = None , expect_failure = False , env = None , ** kwargs
55+ cmd ,
56+ forbidden_output = None ,
57+ expect_failure = False ,
58+ env = None ,
59+ allowed_failure_output = None ,
60+ ** kwargs
5661):
5762 if forbidden_output is None :
5863 forbidden_output = []
64+ if allowed_failure_output is None :
65+ allowed_failure_output = []
5966
6067 command_string = ' ' .join (cmd )
6168
6269 print_divider ('>' )
6370 print ('Running command "%s"' % command_string )
6471
6572 start_time = time .time ()
66- stdout_pipe = sys .stdout if not forbidden_output else subprocess .PIPE
67- stderr_pipe = sys .stderr if not forbidden_output else subprocess .PIPE
73+ collect_output = forbidden_output or allowed_failure_output
74+ stdout_pipe = sys .stdout if not collect_output else subprocess .PIPE
75+ stderr_pipe = sys .stderr if not collect_output else subprocess .PIPE
6876 process = subprocess .Popen (
6977 cmd ,
7078 stdout = stdout_pipe ,
@@ -92,10 +100,17 @@ def run_cmd(
92100
93101 print_divider ('!' )
94102
95- raise Exception (
96- 'Command "%s" exited with code %d.' %
97- (command_string , process .returncode )
98- )
103+ allowed_failure = False
104+ for allowed_string in allowed_failure_output :
105+ if (stdout and allowed_string in stdout ) or (stderr and
106+ allowed_string in stderr ):
107+ allowed_failure = True
108+
109+ if not allowed_failure :
110+ raise Exception (
111+ 'Command "%s" exited with code %d.' %
112+ (command_string , process .returncode )
113+ )
99114
100115 if stdout or stderr :
101116 print (stdout )
@@ -192,6 +207,7 @@ def run_engine_executable( # pylint: disable=too-many-arguments
192207 flags = None ,
193208 cwd = BUILDROOT_DIR ,
194209 forbidden_output = None ,
210+ allowed_failure_output = None ,
195211 expect_failure = False ,
196212 coverage = False ,
197213 extra_env = None ,
@@ -205,6 +221,8 @@ def run_engine_executable( # pylint: disable=too-many-arguments
205221 flags = []
206222 if forbidden_output is None :
207223 forbidden_output = []
224+ if allowed_failure_output is None :
225+ allowed_failure_output = []
208226 if extra_env is None :
209227 extra_env = {}
210228
@@ -249,7 +267,8 @@ def run_engine_executable( # pylint: disable=too-many-arguments
249267 cwd = cwd ,
250268 forbidden_output = forbidden_output ,
251269 expect_failure = expect_failure ,
252- env = env
270+ env = env ,
271+ allowed_failure_output = allowed_failure_output
253272 )
254273 except :
255274 # The LUCI environment may provide a variable containing a directory path
@@ -287,6 +306,7 @@ def __init__( # pylint: disable=too-many-arguments
287306 flags = None ,
288307 cwd = BUILDROOT_DIR ,
289308 forbidden_output = None ,
309+ allowed_failure_output = None ,
290310 expect_failure = False ,
291311 coverage = False ,
292312 extra_env = None ,
@@ -297,6 +317,7 @@ def __init__( # pylint: disable=too-many-arguments
297317 self .flags = flags
298318 self .cwd = cwd
299319 self .forbidden_output = forbidden_output
320+ self .allowed_failure_output = allowed_failure_output
300321 self .expect_failure = expect_failure
301322 self .coverage = coverage
302323 self .extra_env = extra_env
@@ -309,6 +330,7 @@ def __call__(self, *args):
309330 flags = self .flags ,
310331 cwd = self .cwd ,
311332 forbidden_output = self .forbidden_output ,
333+ allowed_failure_output = self .allowed_failure_output ,
312334 expect_failure = self .expect_failure ,
313335 coverage = self .coverage ,
314336 extra_env = self .extra_env ,
@@ -442,28 +464,32 @@ def make_test(name, flags=None, extra_env=None):
442464 shuffle_flags ,
443465 coverage = coverage
444466 )
445- # TODO(117122): Re-enable impeller_unittests after shader compiler errors
446- # are addressed.
447467 # Impeller tests are only supported on macOS for now.
448- # run_engine_executable(
449- # build_dir,
450- # 'impeller_unittests',
451- # executable_filter,
452- # shuffle_flags,
453- # coverage=coverage,
454- # extra_env={
455- # # pylint: disable=line-too-long
456- # # See https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc
457- # 'MTL_SHADER_VALIDATION':
458- # '1', # Enables all shader validation tests.
459- # 'MTL_SHADER_VALIDATION_GLOBAL_MEMORY':
460- # '1', # Validates accesses to device and constant memory.
461- # 'MTL_SHADER_VALIDATION_THREADGROUP_MEMORY':
462- # '1', # Validates accesses to threadgroup memory.
463- # 'MTL_SHADER_VALIDATION_TEXTURE_USAGE':
464- # '1', # Validates that texture references are not nil.
465- # }
466- # )
468+ run_engine_executable (
469+ build_dir ,
470+ 'impeller_unittests' ,
471+ executable_filter ,
472+ shuffle_flags ,
473+ coverage = coverage ,
474+ extra_env = {
475+ # pylint: disable=line-too-long
476+ # See https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc
477+ 'MTL_SHADER_VALIDATION' :
478+ '1' , # Enables all shader validation tests.
479+ 'MTL_SHADER_VALIDATION_GLOBAL_MEMORY' :
480+ '1' , # Validates accesses to device and constant memory.
481+ 'MTL_SHADER_VALIDATION_THREADGROUP_MEMORY' :
482+ '1' , # Validates accesses to threadgroup memory.
483+ 'MTL_SHADER_VALIDATION_TEXTURE_USAGE' :
484+ '1' , # Validates that texture references are not nil.
485+ },
486+ # TODO(117122): Remove this allowlist.
487+ # https://github.com/flutter/flutter/issues/114872
488+ allowed_failure_output = [
489+ '[MTLCompiler createVertexStageAndLinkPipelineWithFragment:' ,
490+ '[MTLCompiler pipelineStateWithVariant:' ,
491+ ]
492+ )
467493
468494
469495def parse_impeller_vulkan_filter ():
0 commit comments