summaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
Diffstat (limited to 'test/py')
-rw-r--r--test/py/multiplexed_log.py8
-rw-r--r--test/py/requirements.txt2
-rw-r--r--test/py/tests/test_efi_secboot/conftest.py5
-rw-r--r--test/py/tests/test_efi_secboot/test_signed.py9
-rw-r--r--test/py/tests/test_efi_secboot/test_signed_intca.py9
-rw-r--r--test/py/tests/test_efi_secboot/test_unsigned.py9
-rw-r--r--test/py/tests/test_fw_handoff.py108
-rw-r--r--test/py/tests/test_of_migrate.py105
8 files changed, 144 insertions, 111 deletions
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index 63237594bb4..68dc183e463 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -138,10 +138,10 @@ class RunAndLog(object):
self.logfile.write(self, msg)
try:
- p = subprocess.Popen(cmd, cwd=cwd,
- stdin=subprocess.PIPE if stdin else None,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
- (stdout, stderr) = p.communicate(input=stdin)
+ p = subprocess.run(cmd, cwd=cwd, capture_output=True, input=stdin,
+ env=env)
+ stdout = p.stdout
+ stderr = p.stderr
if stdout is not None:
stdout = stdout.decode('utf-8')
if stderr is not None:
diff --git a/test/py/requirements.txt b/test/py/requirements.txt
index 804a427b351..f9eac7901fb 100644
--- a/test/py/requirements.txt
+++ b/test/py/requirements.txt
@@ -1,5 +1,5 @@
filelock==3.0.12
pycryptodomex==3.21.0
-pytest==6.2.5
+pytest==8.4.2
pytest-xdist==2.5.0
FATtools==1.0.42
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
index aa9a3536296..76b8f9fa0a3 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -162,9 +162,12 @@ def efi_boot_env_intca(request, ubman):
# PK
check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ -keyout PK.key -out PK.crt -nodes -days 365'
% mnt_point, shell=True)
- check_call('cd %s; %scert-to-efi-sig-list -g %s PK.crt PK.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth'
+ check_call('cd %s; %scert-to-efi-sig-list -g %s PK.crt PK.esl; %ssign-efi-sig-list -t "2020-04-01" -c PK.crt -k PK.key PK PK.esl PK.auth'
% (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
shell=True)
+ # PK_null for deletion
+ check_call('cd %s; touch PK_null.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK_null.esl PK_null.auth'
+ % (mnt_point, EFITOOLS_PATH), shell=True)
# KEK
check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ -keyout KEK.key -out KEK.crt -nodes -days 365'
% mnt_point, shell=True)
diff --git a/test/py/tests/test_efi_secboot/test_signed.py b/test/py/tests/test_efi_secboot/test_signed.py
index e8aaef7090c..9e6d3fdf8d8 100644
--- a/test/py/tests/test_efi_secboot/test_signed.py
+++ b/test/py/tests/test_efi_secboot/test_signed.py
@@ -369,3 +369,12 @@ class TestEfiSignedImage(object):
assert(not 'hELLO, world!' in ''.join(output))
assert('\'HELLO1\' failed' in ''.join(output))
assert('efi_bootmgr_load() returned: 26' in ''.join(output))
+
+ with ubman.log.section('Test Case 8c'):
+ # Test Case 8c, Uninstall PK
+ output = ubman.run_command_list([
+ 'fatload host 0:1 4000000 PK_null.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
+ 'printenv -e -n PK'])
+ assert 'Failed to set EFI variable' not in ''.join(output)
+ assert '\"PK\" not defined' in ''.join(output)
diff --git a/test/py/tests/test_efi_secboot/test_signed_intca.py b/test/py/tests/test_efi_secboot/test_signed_intca.py
index 58f7be03b8b..06d86baef19 100644
--- a/test/py/tests/test_efi_secboot/test_signed_intca.py
+++ b/test/py/tests/test_efi_secboot/test_signed_intca.py
@@ -133,3 +133,12 @@ class TestEfiSignedImageIntca(object):
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
+
+ with ubman.log.section('Test Case 3c'):
+ # Test Case 3c, Uninstall PK
+ output = ubman.run_command_list([
+ 'fatload host 0:1 4000000 PK_null.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
+ 'printenv -e -n PK'])
+ assert 'Failed to set EFI variable' not in ''.join(output)
+ assert '\"PK\" not defined' in ''.join(output)
diff --git a/test/py/tests/test_efi_secboot/test_unsigned.py b/test/py/tests/test_efi_secboot/test_unsigned.py
index bd6e1b2dadd..2b86dc44cff 100644
--- a/test/py/tests/test_efi_secboot/test_unsigned.py
+++ b/test/py/tests/test_efi_secboot/test_unsigned.py
@@ -115,3 +115,12 @@ class TestEfiUnsignedImage(object):
'efidebug test bootmgr'])
assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
+
+ with ubman.log.section('Test Case 3c'):
+ # Test Case 3c, Uninstall PK
+ output = ubman.run_command_list([
+ 'fatload host 0:1 4000000 PK_null.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK',
+ 'printenv -e -n PK'])
+ assert 'Failed to set EFI variable' not in ''.join(output)
+ assert '\"PK\" not defined' in ''.join(output)
diff --git a/test/py/tests/test_fw_handoff.py b/test/py/tests/test_fw_handoff.py
new file mode 100644
index 00000000000..45f154665ef
--- /dev/null
+++ b/test/py/tests/test_fw_handoff.py
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2025 Linaro Limited
+# Author: Raymond Mao <raymond.mao@linaro.org>
+#
+# Validate Firmware Handoff from TF-A and OP-TEE
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+whether Firmware Handoff is enabled for testing. Without this, this test
+will be automatically skipped.
+
+For example:
+
+.. code-block:: python
+
+ # Boolean indicating whether Firmware Handoff is enabled on this board.
+ # This variable may be omitted if its value is False.
+ env__firmware_handoff_enabled = True
+"""
+
+import pytest
+import re
+
+def _norm_ws(s: str) -> str:
+ """Normalize whitespace for robust comparisons."""
+ return re.sub(r"\s+", " ", s).strip()
+
+@pytest.mark.buildconfigspec("bloblist")
+@pytest.mark.buildconfigspec("cmd_bloblist")
+@pytest.mark.buildconfigspec("of_control")
+@pytest.mark.buildconfigspec("cmd_fdt")
+def test_fw_handoff_dt(ubman):
+ """Validate FDT handoff via bloblist."""
+
+ fh_en = ubman.config.env.get('env__firmware_handoff_enabled', False)
+ if not fh_en:
+ pytest.skip('Firmware Handoff is disabled')
+
+ bloblist = ubman.run_command("bloblist list")
+ blob_fdt = re.search(r"^([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+1\s+Control FDT\s*$",
+ bloblist, re.MULTILINE)
+ assert blob_fdt, "Control FDT entry not found in bloblist"
+
+ blob_fdt_addr = int(blob_fdt.group(1), 16)
+ ubman.run_command(f"fdt addr {blob_fdt_addr:x}")
+
+ reserved_a = ubman.run_command("fdt print /reserved-memory")
+ firmware_a = ubman.run_command("fdt print /firmware")
+
+ fdt_addr_out = ubman.run_command("echo $fdt_addr")
+ fdt_addr_match = re.search(r"(?:0x)?([0-9a-fA-F]+)", fdt_addr_out)
+ assert fdt_addr_match, "Could not parse $fdt_addr"
+
+ fdt_addr = int(fdt_addr_match.group(1), 16)
+ ubman.run_command(f"fdt addr {fdt_addr:x}")
+
+ reserved_b = ubman.run_command("fdt print /reserved-memory")
+ firmware_b = ubman.run_command("fdt print /firmware")
+
+ # Normalize whitespace & compare
+ assert _norm_ws(reserved_a) == _norm_ws(reserved_b), \
+ "reserved-memory blocks differ between Control FDT and $fdt_addr FDT"
+ assert _norm_ws(firmware_a) == _norm_ws(firmware_b), \
+ "firmware blocks differ between Control FDT and $fdt_addr FDT"
+
+@pytest.mark.buildconfigspec("bloblist")
+@pytest.mark.buildconfigspec("cmd_bloblist")
+@pytest.mark.buildconfigspec("cmd_memory")
+def test_fw_handoff_eventlog(ubman):
+ """Validate TPM event log handoff via bloblist."""
+
+ fh_en = ubman.config.env.get('env__firmware_handoff_enabled', False)
+ if not fh_en:
+ pytest.skip('Firmware Handoff is disabled')
+
+ # Get the address and size of eventlog from the bloblist
+ bloblist_output = ubman.run_command("bloblist list")
+ evt_addr = None
+ evt_size = None
+ for line in bloblist_output.splitlines():
+ if "TPM event log" in line:
+ parts = line.strip().split()
+ evt_addr = int(parts[0], 16)
+ evt_size = int(parts[1], 16)
+ break
+
+ assert evt_addr is not None and evt_size is not None, \
+ "TPM event log not found in bloblist"
+
+ # Read byte from memory and extract printable ASCII from each line
+ md_output = ubman.run_command(f"md.b {evt_addr:x} {evt_size}")
+ ascii_log = ""
+ for line in md_output.splitlines():
+ match = re.search(r'([0-9a-f]+:.*?)((?:\s[0-9a-f]{2}){1,16})\s+(.*)', line)
+ if match:
+ ascii_part = match.group(3).strip()
+ ascii_log += ascii_part
+
+ # The events created by TF-A are expected
+ expected_keywords = [
+ "SECURE_RT_EL3",
+ "SECURE_RT_EL1_OPTEE",
+ "SECURE_RT_EL1_OPTEE_EXTRA1"
+ ]
+
+ for keyword in expected_keywords:
+ assert keyword in ascii_log, f"Missing expected event: {keyword}"
diff --git a/test/py/tests/test_of_migrate.py b/test/py/tests/test_of_migrate.py
deleted file mode 100644
index ab89332331e..00000000000
--- a/test/py/tests/test_of_migrate.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Copyright 2023 Google LLC
-# Written by Simon Glass <sjg@chromium.org>
-
-"""Test handling of unmigrated u-boot,dm- tags"""
-
-import os
-import pytest
-
-import utils
-
-# This is needed for Azure, since the default '..' directory is not writeable
-TMPDIR1 = '/tmp/test_no_migrate'
-TMPDIR2 = '/tmp/test_no_migrate_spl'
-TMPDIR3 = '/tmp/test_migrate'
-
-def build_for_migrate(ubman, replace_pair, board, tmpdir, disable_migrate=True):
- """Build an updated U-Boot with a slightly modified device tree
-
- Args:
- ubman (ConsoleBase): U-Boot console
- replace_pair (tuple):
- String to find
- String to replace it with
- board (str): Board to build
- tmpdir (str): Temporary directory to use
- disable_migrate (bool): True to disable CONFIG_OF_TAG_MIGRATE in build
- """
- srcdir = ubman.config.source_dir
- build_dir = ubman.config.build_dir
-
- # Get the source for the existing dts
- dt_dir = os.path.join(build_dir, 'arch', 'sandbox', 'dts')
- orig_fname = os.path.join(dt_dir, 'sandbox.dtb')
- out_dts = os.path.join(dt_dir, 'sandbox_out.dts')
- utils.run_and_log(ubman, ['dtc', orig_fname, '-I', 'dtb', '-O', 'dts',
- '-o', out_dts])
-
- # Update it to use an old tag
- with open(out_dts) as inf:
- data = inf.read()
- data = data.replace(*replace_pair)
-
- dts_fname = os.path.join(dt_dir, 'sandbox_oldtag.dts')
- with open(dts_fname, 'w') as outf:
- print(data, file=outf)
- dtb_fname = os.path.join(dt_dir, 'sandbox_oldtag.dtb')
- utils.run_and_log(ubman, ['dtc', dts_fname, '-o', dtb_fname])
-
- migrate = ['-a', '~CONFIG_OF_TAG_MIGRATE'] if disable_migrate else []
-
- # Build sandbox with this new dtb, turning off OF_TAG_MIGRATE
- env = dict(os.environ)
- env['EXT_DTB'] = dtb_fname
- env['DEVICE_TREE'] = 'sandbox_new'
- env['NO_LTO'] = '1' # Speed up build
- out = utils.run_and_log(
- ubman, ['./tools/buildman/buildman', '-m', '--board', board,
- *migrate, '-w', '-o', tmpdir], ignore_errors=True, env=env)
- return out
-
-@pytest.mark.slow
-@pytest.mark.boardspec('sandbox')
-def test_of_no_migrate(ubman):
- """Test sandbox with old boot phase tags like u-boot,dm-pre-proper"""
-
- build_for_migrate(ubman, ['bootph-some-ram', 'u-boot,dm-pre-proper'],
- 'sandbox', TMPDIR1)
-
- # It should fail to run, since the lcd device will not be bound before
- # relocation. so won't get its frame-buffer memory
- out = utils.run_and_log(
- ubman, [os.path.join(TMPDIR1, 'u-boot'), '-D', '-c', 'help'],
- ignore_errors=True)
- assert "Video device 'lcd' cannot allocate frame buffer memory" in out
-
-
-@pytest.mark.slow
-@pytest.mark.boardspec('sandbox_spl')
-@pytest.mark.boardspec('spl_of_platdata_inst')
-@pytest.mark.boardspec('!sandbox_tpl')
-def test_of_no_migrate_spl(ubman):
- """Test sandbox with old boot phase tags like u-boot,dm-spl"""
-
- out = build_for_migrate(ubman, ['bootph-pre-ram', 'u-boot,dm-spl'],
- 'sandbox_spl', TMPDIR2)
-
- # It should fail to build, since the SPL DT will not include 'spl-test'
- # node, among others
- assert "undefined type ‘struct dtd_sandbox_spl_test’" in out
-
-
-@pytest.mark.slow
-@pytest.mark.boardspec('sandbox')
-def test_of_migrate(ubman):
- """Test sandbox shows a message when tags were migrated"""
-
- build_for_migrate(ubman, ['bootph-some-ram', 'u-boot,dm-pre-proper'],
- 'sandbox', TMPDIR3, disable_migrate=False)
-
- # It should show a migration message
- out = utils.run_and_log(
- ubman, [os.path.join(TMPDIR3, 'u-boot'), '-D', '-c', 'help'],
- ignore_errors=True)
- assert "Warning: Device tree includes old 'u-boot,dm-' tags" in out