tests/misc: Add llext EDK test
This test uses pytest to generate an EDK from a simple Zephyr application, and uses this EDK to build a simple extension, to ensure that EDK generation is sane. Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
parent
4e9a2a7c33
commit
a0ee472a6f
10 changed files with 195 additions and 0 deletions
|
@ -36,3 +36,12 @@ foreach(file_name include/stddef.h)
|
|||
|
||||
list(APPEND NOSTDINC ${_OUTPUT})
|
||||
endforeach()
|
||||
|
||||
list(APPEND LLEXT_EDK_REMOVE_FLAGS
|
||||
--sysroot=.*
|
||||
-fmacro-prefix-map=.*
|
||||
)
|
||||
|
||||
list(APPEND LLEXT_EDK_APPEND_FLAGS
|
||||
-nodefaultlibs
|
||||
)
|
||||
|
|
9
tests/misc/llext-edk/CMakeLists.txt
Normal file
9
tests/misc/llext-edk/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(llext_edk_test LANGUAGES C)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
||||
zephyr_include_directories(include)
|
||||
zephyr_include_directories($ENV{ZEPHYR_BASE}/boards/native/common)
|
23
tests/misc/llext-edk/extension/CMakeLists.txt
Normal file
23
tests/misc/llext-edk/extension/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
project(extension)
|
||||
|
||||
include($ENV{LLEXT_EDK_INSTALL_DIR}/cmake.cflags)
|
||||
|
||||
# Add LLEXT_CFLAGS to our flags
|
||||
add_compile_options(${LLEXT_CFLAGS})
|
||||
add_compile_options("-Werror")
|
||||
add_compile_options("-c")
|
||||
|
||||
# Get flags from COMPILE_OPTIONS
|
||||
get_property(COMPILE_OPTIONS_PROP DIRECTORY PROPERTY COMPILE_OPTIONS)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext
|
||||
COMMAND ${CMAKE_C_COMPILER} ${COMPILE_OPTIONS_PROP}
|
||||
-o ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext
|
||||
${PROJECT_SOURCE_DIR}/src/main.c
|
||||
)
|
||||
|
||||
add_custom_target(extension ALL DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.llext)
|
17
tests/misc/llext-edk/extension/src/main.c
Normal file
17
tests/misc/llext-edk/extension/src/main.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <app_api.h>
|
||||
|
||||
int start(void)
|
||||
{
|
||||
int bar = 42;
|
||||
|
||||
printk("foo(%d) is %d\n", bar, foo(bar));
|
||||
return 0;
|
||||
}
|
22
tests/misc/llext-edk/include/app_api.h
Normal file
22
tests/misc/llext-edk/include/app_api.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TEST_EDK_H_
|
||||
#define _TEST_EDK_H_
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__syscall int foo(int bar);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <syscalls/app_api.h>
|
||||
#endif /* _TEST_EDK_H_ */
|
3
tests/misc/llext-edk/prj.conf
Normal file
3
tests/misc/llext-edk/prj.conf
Normal file
|
@ -0,0 +1,3 @@
|
|||
CONFIG_APPLICATION_DEFINED_SYSCALL=y
|
||||
#CONFIG_USERSPACE=y
|
||||
CONFIG_LLEXT=y
|
66
tests/misc/llext-edk/pytest/test_edk.py
Normal file
66
tests/misc/llext-edk/pytest/test_edk.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
# 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
|
||||
from twister_harness import DeviceAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def test_edk(dut: DeviceAdapter):
|
||||
# Can we build the edk?
|
||||
command = [
|
||||
"west",
|
||||
"build",
|
||||
"-t",
|
||||
"llext-edk",
|
||||
"--build-dir",
|
||||
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(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)
|
||||
|
||||
# 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")
|
23
tests/misc/llext-edk/src/foo.c
Normal file
23
tests/misc/llext-edk/src/foo.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <app_api.h>
|
||||
#include <app_api.h>
|
||||
|
||||
int z_impl_foo(int bar)
|
||||
{
|
||||
return bar * bar;
|
||||
}
|
||||
EXPORT_SYMBOL(z_impl_foo);
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
static inline int z_vrfy_foo(int bar)
|
||||
{
|
||||
/* Nothing to verify */
|
||||
return z_impl_foo(bar);
|
||||
}
|
||||
#include <syscalls/foo_mrsh.c>
|
||||
#endif
|
14
tests/misc/llext-edk/src/main.c
Normal file
14
tests/misc/llext-edk/src/main.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <app_api.h>
|
||||
|
||||
#include <zephyr/llext/llext.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
9
tests/misc/llext-edk/testcase.yaml
Normal file
9
tests/misc/llext-edk/testcase.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
tests:
|
||||
misc.edk.pytest:
|
||||
harness: pytest
|
||||
tags:
|
||||
- pytest
|
||||
- edk
|
||||
platform_allow:
|
||||
- native_sim
|
||||
toolchain_exclude: llvm
|
Loading…
Add table
Add a link
Reference in a new issue