Edit

IABSD.fr/xenocara/lib/mesa/bin/nir-test-runner.py

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2025-06-05 11:23:11
    Hash : 67d6f117
    Message : Import Mesa 25.0.7

  • lib/mesa/bin/nir-test-runner.py
  • #!/usr/bin/env python3
    
    # Copyright © 2024 Valve Corporation
    # SPDX-License-Identifier: MIT
    
    import argparse
    import collections
    import subprocess
    import os
    import re
    import sys
    import tempfile
    import textwrap
    from pathlib import Path
    
    class TestFileChange:
        def __init__(self, line, result):
            self.line = line
            self.result = result
    
    class TestFileChanges:
        def __init__(self, name):
            self.name = name
            self.changes = []
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument('--build-dir', '-B', required=False)
        parser.add_argument('--test-filter', '-f', required=False)
        parser.add_argument('--update-all', '-u', action='store_true')
        args = parser.parse_args()
    
        bin_path = 'src/compiler/nir/nir_tests'
        if args.build_dir:
            bin_path = args.build_dir + '/' + bin_path
    
        if not os.path.isfile(bin_path):
            print(f'{bin_path} \033[91m does not exist!\033[0m')
            exit(1)
    
        build_args = ['meson', 'compile']
        if args.build_dir:
            build_args.append(f'-C{args.build_dir}')
        subprocess.run(build_args)
    
        test_args = [bin_path]
        if args.test_filter:
            test_args.append(f'--gtest_filter={args.test_filter}')
    
        env = os.environ.copy()
        if args.update_all:
            env['NIR_TEST_DUMP_SHADERS'] = 'true'
    
        output = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, env=env)
    
        expected_pattern = re.compile(r'Expected \(([\d\w\W/.-_]+):(\d+)\):')
    
        test_result = None
        expectations = collections.defaultdict(list)
    
        # Parse the output of the test binary and gather the changed shaders.
        for output_line in output.stdout.split('\n'):
            if output_line.startswith('Got:'):
                test_result = ''
    
                continue
    
            if output_line.startswith('Expected ('):
                match = expected_pattern.match(output_line)
                file = match.group(1).removeprefix('../')
                line = int(match.group(2))
    
                expectations[file].append(TestFileChange(line, test_result.strip()))
    
                test_result = None
    
                continue
    
            if test_result is not None:
                test_result += output_line + '\n'
    
        patches = []
    
        # Generate patches for the changed shaders.
        for file in expectations:
            changes = expectations[file]
    
            updated_test_file = ''
            change_index = 0
            line_index = 1
            inside_expectation = False
    
            with open(file) as test_file:
                for test_line in test_file:
                    if test_line.strip().startswith(')\"'):
                        inside_expectation = False
    
                    if not inside_expectation:
                        updated_test_file += test_line
    
                    if change_index < len(changes) and line_index == changes[change_index].line:
                        inside_expectation = True
                        indentation = len(test_line) - len(test_line.lstrip()) + 3
                        updated_test_file += textwrap.indent(changes[change_index].result, " " * indentation) + '\n'
                        change_index += 1
    
                    line_index += 1
    
            with tempfile.NamedTemporaryFile(delete_on_close=False) as tmp:
                tmp.write(bytes(updated_test_file, encoding="utf-8"))
                tmp.close()
    
                diff = subprocess.run(
                    ['git', 'diff', '--no-index', file, tmp.name],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    universal_newlines=True,
                )
                patch = diff.stdout.replace(tmp.name, '/' + file)
    
                print(patch)
    
                patches.append(patch)
    
        if len(patches) != 0:
            sys.stdout.write('\033[96mApply the changes listed above?\033[0m [Y/n]')
            response = None
            try:
                response = input()
            except KeyboardInterrupt:
                print()
                sys.exit(1)
    
            if response in ['', 'y', 'Y']:
                for patch in patches:
                    apply = subprocess.Popen(
                        ['git', 'apply', '--allow-empty'],
                        stdin=subprocess.PIPE,
                    )
                    apply.communicate(input=bytes(patch, encoding="utf-8"))