You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
4.5 KiB
113 lines
4.5 KiB
# Copyright (c) 2024 Intel Corporation |
|
# |
|
# SPDX-License-Identifier: Apache-2.0 |
|
|
|
import logging |
|
import os |
|
import shutil |
|
import tempfile |
|
from pathlib import Path |
|
from subprocess import check_output |
|
|
|
import pytest |
|
from twister_harness import DeviceAdapter |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
def test_edk(unlaunched_dut: DeviceAdapter): |
|
# Need to have the ZEPHYR_SDK_INSTALL_DIR environment variable set, |
|
# otherwise can't actually build the edk |
|
if os.environ.get("ZEPHYR_SDK_INSTALL_DIR") is None: |
|
logger.warning("ZEPHYR_SDK_INSTALL_DIR is not set, skipping test") |
|
pytest.skip("ZEPHYR_SDK_INSTALL_DIR is not set") |
|
|
|
# Can we build the edk? |
|
command = [ |
|
"west", |
|
"build", |
|
"-b", |
|
unlaunched_dut.device_config.platform, |
|
"-t", |
|
"llext-edk", |
|
"--build-dir", |
|
unlaunched_dut.device_config.build_dir, |
|
] |
|
output = check_output(command, text=True) |
|
logger.info(output) |
|
|
|
# Install the edk to a temporary location |
|
with tempfile.TemporaryDirectory() as tempdir: |
|
# Copy the edk to the temporary directory using python methods |
|
logger.debug(f"Copying llext-edk.tar.xz to {tempdir}") |
|
edk_path = Path(unlaunched_dut.device_config.build_dir) / "zephyr/llext-edk.tar.xz" |
|
shutil.copy(edk_path, tempdir) |
|
|
|
# Extract the edk using tar |
|
logger.debug(f"Extracting llext-edk.tar.xz to {tempdir}") |
|
command = ["tar", "-xf", "llext-edk.tar.xz"] |
|
output = check_output(command, text=True, cwd=tempdir) |
|
logger.info(output) |
|
|
|
# Copy the extension to another temporary directory to test out of tree builds |
|
with tempfile.TemporaryDirectory() as tempdir_extension: |
|
logger.debug(f"Copying extension to {tempdir_extension}") |
|
ext_dir = Path(os.environ["ZEPHYR_BASE"]) / "tests/misc/llext-edk/extension" |
|
shutil.copytree(ext_dir, tempdir_extension, dirs_exist_ok=True) |
|
|
|
# Also copy file2hex.py to the extension directory, so that it's possible |
|
# to generate a hex file from the extension binary |
|
logger.debug(f"Copying file2hex.py to {tempdir_extension}") |
|
file2hex = Path(os.environ["ZEPHYR_BASE"]) / "scripts/build/file2hex.py" |
|
shutil.copy(file2hex, tempdir_extension) |
|
|
|
# Set the LLEXT_EDK_INSTALL_DIR environment variable so that the extension |
|
# knows where the EDK is installed |
|
edk_dir = Path(tempdir) / "llext-edk" |
|
env = os.environ.copy() |
|
env.update({"LLEXT_EDK_INSTALL_DIR": edk_dir}) |
|
|
|
# Build the extension using the edk |
|
logger.debug(f"Building extension in {tempdir_extension} - cmake") |
|
command = ["cmake", "-B", "build"] |
|
output = check_output(command, text=True, cwd=tempdir_extension, env=env) |
|
logger.info(output) |
|
|
|
logger.debug(f"Building extension in {tempdir_extension} - make") |
|
command = ["make", "-C", "build"] |
|
output = check_output(command, text=True, cwd=tempdir_extension, env=env) |
|
logger.info(output) |
|
|
|
# Check if the extension was built |
|
assert os.path.exists(Path(tempdir_extension) / "build/extension.llext") |
|
|
|
# Can we run it? First, rebuild the application, now including the extension |
|
# build directory in the include path, so that the application can find the |
|
# extension code. |
|
logger.debug(f"Running application with extension in {tempdir_extension} - west build") |
|
command = [ |
|
"west", |
|
"build", |
|
"-b", |
|
unlaunched_dut.device_config.platform, |
|
"--build-dir", |
|
unlaunched_dut.device_config.build_dir, |
|
"--", |
|
f"-DEXTENSION_DIR={tempdir_extension}/build/" |
|
] |
|
logger.debug(f"west command: {command}") |
|
output = check_output(command, text=True) |
|
logger.info(output) |
|
|
|
# Now that the application is built, run it |
|
logger.debug(f"Running application with extension in {tempdir_extension}") |
|
try: |
|
unlaunched_dut.launch() |
|
lines = unlaunched_dut.readlines_until("Done") |
|
|
|
assert "Calling extension from kernel" in lines |
|
assert "Calling extension from user" in lines |
|
assert "foo(42) is 1764" in lines |
|
assert "foo(43) is 1849" in lines |
|
|
|
finally: |
|
unlaunched_dut.close()
|
|
|