Read patch files instead of taking a single patch as input

Having separate patch files has several benefits:

* They're available for integrators who wouldn't use our script to
  test compliance.
* We keep them separate so they're easier for us to keep track of,
  and apply separately if needed.
* No need to cheat with unchanged empty lines (normally represented by
  a line containing a single space in a patch file) to keep `check_files.py`
  happy.

Signed-off-by: Gilles Peskine <[email protected]>
This commit is contained in:
Gilles Peskine
2025-09-12 17:46:42 +02:00
parent ca98305f7f
commit 1295140bca
+19 -9
View File
@@ -10,8 +10,10 @@ keep the list of known defects as up to date as possible.
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
import argparse import argparse
import glob
import os import os
import re import re
import shlex
import shutil import shutil
import subprocess import subprocess
import sys import sys
@@ -25,7 +27,7 @@ PSA_ARCH_TESTS_REPO = 'https://github.com/ARM-software/psa-arch-tests.git'
#pylint: disable=too-many-branches,too-many-statements,too-many-locals #pylint: disable=too-many-branches,too-many-statements,too-many-locals
def test_compliance(library_build_dir: str, def test_compliance(library_build_dir: str,
psa_arch_tests_ref: str, psa_arch_tests_ref: str,
patch: str, patch_files: List[str],
expected_failures: List[int]) -> int: expected_failures: List[int]) -> int:
"""Check out and run compliance tests. """Check out and run compliance tests.
@@ -59,12 +61,12 @@ def test_compliance(library_build_dir: str,
subprocess.check_call(['git', 'fetch', PSA_ARCH_TESTS_REPO, psa_arch_tests_ref]) subprocess.check_call(['git', 'fetch', PSA_ARCH_TESTS_REPO, psa_arch_tests_ref])
subprocess.check_call(['git', 'checkout', '--force', 'FETCH_HEAD']) subprocess.check_call(['git', 'checkout', '--force', 'FETCH_HEAD'])
if patch: if patch_files:
subprocess.check_call(['git', 'reset', '--hard']) subprocess.check_call(['git', 'reset', '--hard'])
subprocess.run(['patch', '-p1'], for patch_file in patch_files:
check=True, abs_path = os.path.abspath(os.path.join(root_dir, patch_file))
encoding='utf-8', subprocess.check_call(['patch -p1 <' + shlex.quote(abs_path)],
input=patch) shell=True)
build_dir = 'api-tests/build' build_dir = 'api-tests/build'
try: try:
@@ -143,15 +145,15 @@ def test_compliance(library_build_dir: str,
os.chdir(root_dir) os.chdir(root_dir)
def main(psa_arch_tests_ref: str, def main(psa_arch_tests_ref: str,
patch: str = '',
expected_failures: Optional[List[int]] = None) -> None: expected_failures: Optional[List[int]] = None) -> None:
"""Command line entry point. """Command line entry point.
psa_arch_tests_ref: tag or sha to use for the arch-tests. psa_arch_tests_ref: tag or sha to use for the arch-tests.
patch: patch to apply to the arch-tests with ``patch -p1``.
expected_failures: default list of expected failures. expected_failures: default list of expected failures.
""" """
build_dir = 'out_of_source_build' build_dir = 'out_of_source_build'
default_patch_directory = os.path.join(build_tree.guess_project_root(),
'scripts/data_files/psa-arch-tests')
# pylint: disable=invalid-name # pylint: disable=invalid-name
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@@ -161,6 +163,9 @@ def main(psa_arch_tests_ref: str,
help='''set the list of test codes which are expected to fail help='''set the list of test codes which are expected to fail
from the command line. If omitted the list given by from the command line. If omitted the list given by
EXPECTED_FAILURES (inside the script) is used.''') EXPECTED_FAILURES (inside the script) is used.''')
parser.add_argument('--patch-directory', nargs=1,
default=default_patch_directory,
help='Directory containing patches (*.patch) to apply to psa-arch-tests')
args = parser.parse_args() args = parser.parse_args()
if args.build_dir is not None: if args.build_dir is not None:
@@ -173,7 +178,12 @@ def main(psa_arch_tests_ref: str,
else: else:
expected_failures_list = expected_failures expected_failures_list = expected_failures
if args.patch_directory:
patch_files = glob.glob(os.path.join(args.patch_directory, '*.patch'))
else:
patch_files = []
sys.exit(test_compliance(build_dir, sys.exit(test_compliance(build_dir,
psa_arch_tests_ref, psa_arch_tests_ref,
patch, patch_files,
expected_failures_list)) expected_failures_list))