mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2026-04-18 10:17:38 +00:00
tests(unit): Add llm-enhanced-test submodule integration (#4888)
Signed-off-by: zhenweijin <zhenwei.jin@intel.com>
This commit is contained in:
parent
d0f8ac0e7d
commit
5915e07a32
|
|
@ -323,6 +323,8 @@ jobs:
|
|||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Get LLVM libraries
|
||||
id: retrieve_llvm_libs
|
||||
|
|
|
|||
61
.github/workflows/nightly_run.yml
vendored
61
.github/workflows/nightly_run.yml
vendored
|
|
@ -272,6 +272,67 @@ jobs:
|
|||
cmake --build . --config Release --parallel 4
|
||||
working-directory: product-mini/platforms/${{ matrix.platform }}
|
||||
|
||||
build_unit_tests:
|
||||
needs: [build_llvm_libraries_on_ubuntu_2204, build_wamrc]
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04]
|
||||
build_target: ["X86_64", "X86_32"]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Get LLVM libraries
|
||||
id: retrieve_llvm_libs
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
./core/deps/llvm/build/bin
|
||||
./core/deps/llvm/build/include
|
||||
./core/deps/llvm/build/lib
|
||||
./core/deps/llvm/build/libexec
|
||||
./core/deps/llvm/build/share
|
||||
key: ${{ matrix.llvm_cache_key }}
|
||||
|
||||
- name: Quit if cache miss
|
||||
if: (steps.retrieve_llvm_libs.outputs.cache-hit != 'true')
|
||||
run: echo "::error::can not get prebuilt llvm libraries" && exit 1
|
||||
|
||||
- name: install-wasi-sdk-wabt
|
||||
uses: ./.github/actions/install-wasi-sdk-wabt
|
||||
with:
|
||||
os: ${{ matrix.os }}
|
||||
|
||||
- name: Build wamrc
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release --parallel 4
|
||||
working-directory: wamr-compiler
|
||||
|
||||
- name: Install dependencies for X86_32
|
||||
if: matrix.build_target == 'X86_32'
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y g++-multilib libzstd-dev:i386 zlib1g-dev:i386
|
||||
|
||||
- name: Build and run unit tests
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DWAMR_BUILD_TARGET=${{ matrix.build_target }} -DFULL_TEST=ON
|
||||
cmake --build . --parallel 4
|
||||
ctest --output-on-failure
|
||||
working-directory: tests/unit
|
||||
|
||||
build_iwasm_linux_gcc4_8:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
|
|
|
|||
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[submodule "tests/unit/llm-enhanced-test"]
|
||||
path = tests/unit/llm-enhanced-test
|
||||
url = https://github.com/wasm-micro-runtime/llm-enhanced-test.git
|
||||
branch = main
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(unit-test)
|
||||
option(FULL_TEST "Build all unit tests including llm-enhanced-test" OFF)
|
||||
|
||||
# Yes. To solve the compatibility issue with CMAKE (>= 4.0), we need to update
|
||||
# our `cmake_minimum_required()` to 3.5. However, there are CMakeLists.txt
|
||||
|
|
@ -87,10 +88,16 @@ add_subdirectory(linux-perf)
|
|||
add_subdirectory(gc)
|
||||
add_subdirectory(tid-allocator)
|
||||
add_subdirectory(unsupported-features)
|
||||
add_subdirectory(smart-tests)
|
||||
add_subdirectory(exception-handling)
|
||||
add_subdirectory(running-modes)
|
||||
|
||||
if(FULL_TEST)
|
||||
message(STATUS "FULL_TEST=ON: include llm-enhanced-test")
|
||||
add_subdirectory(llm-enhanced-test)
|
||||
else()
|
||||
message(STATUS "FULL_TEST=OFF: exclude llm-enhanced-test")
|
||||
endif()
|
||||
|
||||
if(WAMR_BUILD_TARGET STREQUAL "X86_64")
|
||||
add_subdirectory(aot-stack-frame)
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,22 @@ When creating a `CMakeLists.txt` file for your test suite, follow these best pra
|
|||
|
||||
---
|
||||
|
||||
## Initializing Submodules
|
||||
|
||||
Test suite `llm-enhanced-test` is maintained in separate repository and included as git submodule. You need to initialize it before building.
|
||||
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
Alternatively, if you haven't cloned the repository yet, use `--recursive` when cloning:
|
||||
|
||||
```bash
|
||||
git clone --recursive https://github.com/bytecodealliance/wasm-micro-runtime.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Compiling and Running Test Cases
|
||||
|
||||
To compile and run the test cases, follow these steps:
|
||||
|
|
@ -102,6 +118,13 @@ To compile and run the test cases, follow these steps:
|
|||
cmake -S . -B build
|
||||
```
|
||||
|
||||
By default, all unit tests except `llm-enhanced-test` are built (`-DFULL_TEST=OFF`).
|
||||
To also include `llm-enhanced-test`, configure with:
|
||||
|
||||
```bash
|
||||
cmake -S . -B build -DFULL_TEST=ON
|
||||
```
|
||||
|
||||
2. **Build the Test Suite**:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
1
tests/unit/llm-enhanced-test
Submodule
1
tests/unit/llm-enhanced-test
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 36c74f6718e5f028c96d99137cb970e708d9838b
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Enhanced Unit Test CMakeLists.txt
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
add_subdirectory(interpreter)
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project (smart-test-interpreter)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
add_definitions (-Dattr_container_malloc=malloc)
|
||||
add_definitions (-Dattr_container_free=free)
|
||||
# add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
|
||||
|
||||
set(WAMR_BUILD_AOT 0)
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_APP_FRAMEWORK 1)
|
||||
|
||||
include (../../unit_common.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
set (UNIT_SOURCE ${source_all})
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${WAMR_RUNTIME_LIB_SOURCE}
|
||||
)
|
||||
|
||||
add_executable (smart_test_classic-interpreter ${unit_test_sources})
|
||||
target_compile_definitions(smart_test_classic-interpreter PUBLIC -DWAMR_BUILD_FAST_INTERP=0)
|
||||
target_link_libraries (smart_test_classic-interpreter gtest_main)
|
||||
|
||||
add_executable (smart_test_fast-interpreter ${unit_test_sources})
|
||||
target_compile_definitions(smart_test_fast-interpreter PUBLIC -DWAMR_BUILD_FAST_INTERP=1)
|
||||
target_link_libraries (smart_test_fast-interpreter gtest_main)
|
||||
|
||||
# Copy WASM files to build directory for classic interpreter
|
||||
# fast interpreter uses the same WASM files
|
||||
add_custom_command(TARGET smart_test_classic-interpreter POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_LIST_DIR}/wasm-apps/*.wasm
|
||||
${CMAKE_CURRENT_BINARY_DIR}/
|
||||
COMMENT "Copy test wasm files to the directory of google test"
|
||||
)
|
||||
|
||||
gtest_discover_tests(smart_test_classic-interpreter)
|
||||
gtest_discover_tests(smart_test_fast-interpreter)
|
||||
|
|
@ -1,454 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "test_helper.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
#include "wasm_runtime_common.h"
|
||||
#include "wasm_runtime.h"
|
||||
#include "wasm_interp.h"
|
||||
#include "wasm_loader.h"
|
||||
|
||||
static std::string CWD;
|
||||
static std::string WASM_FILE;
|
||||
static constexpr uint32_t STACK_SIZE = 8092;
|
||||
static constexpr uint32_t HEAP_SIZE = 8092;
|
||||
|
||||
static int
|
||||
test_import_add_impl(wasm_exec_env_t exec_env, int32_t a, int32_t b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static int
|
||||
test_import_mul_impl(wasm_exec_env_t exec_env, int32_t a, int32_t b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
static int
|
||||
malloc_impl(wasm_exec_env_t exec_env, int32_t size)
|
||||
{
|
||||
return wasm_runtime_module_malloc(
|
||||
wasm_runtime_get_module_inst(exec_env), size, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
free_impl(wasm_exec_env_t exec_env, int32_t ptr)
|
||||
{
|
||||
wasm_runtime_module_free(
|
||||
wasm_runtime_get_module_inst(exec_env), ptr);
|
||||
}
|
||||
|
||||
static int
|
||||
native_func_impl(wasm_exec_env_t exec_env, int32_t a)
|
||||
{
|
||||
return a * 2;
|
||||
}
|
||||
|
||||
static NativeSymbol native_symbols[] = {
|
||||
{ "test_import_add", (void*)test_import_add_impl, "(ii)i", NULL },
|
||||
{ "test_import_mul", (void*)test_import_mul_impl, "(ii)i", NULL },
|
||||
{ "malloc", (void*)malloc_impl, "(i)i", NULL },
|
||||
{ "free", (void*)free_impl, "(i)", NULL },
|
||||
{ "native_func", (void*)native_func_impl, "(i)i", NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* Test fixture for Step 3: Function Invocation and Stack Operations
|
||||
* Targets 6 functions: call_indirect, wasm_call_indirect, wasm_interp_call_func_import,
|
||||
* copy_stack_values, execute_malloc_function, execute_free_function
|
||||
*/
|
||||
class FunctionInvocationTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
char *current_dir = getcwd(NULL, 0);
|
||||
CWD = std::string(current_dir);
|
||||
free(current_dir);
|
||||
WASM_FILE = CWD + "/function_invocation_test.wasm";
|
||||
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
init_args.mem_alloc_type = Alloc_With_System_Allocator;
|
||||
|
||||
ASSERT_TRUE(wasm_runtime_full_init(&init_args));
|
||||
|
||||
// Register native symbols for import testing
|
||||
ASSERT_TRUE(wasm_runtime_register_natives("env", native_symbols,
|
||||
sizeof(native_symbols) / sizeof(NativeSymbol)));
|
||||
|
||||
load_wasm_file();
|
||||
instantiate_module();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
if (exec_env) {
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
}
|
||||
if (module_inst) {
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
}
|
||||
if (module) {
|
||||
wasm_runtime_unload(module);
|
||||
}
|
||||
if (wasm_file_buf) {
|
||||
delete[] wasm_file_buf;
|
||||
}
|
||||
wasm_runtime_destroy();
|
||||
}
|
||||
|
||||
void load_wasm_file()
|
||||
{
|
||||
std::ifstream wasm_file(WASM_FILE, std::ios::binary);
|
||||
ASSERT_TRUE(wasm_file.is_open()) << "Failed to open WASM file: " << WASM_FILE;
|
||||
|
||||
std::vector<uint8_t> buffer(std::istreambuf_iterator<char>(wasm_file), {});
|
||||
wasm_file_size = buffer.size();
|
||||
wasm_file_buf = new unsigned char[wasm_file_size];
|
||||
std::copy(buffer.begin(), buffer.end(), wasm_file_buf);
|
||||
|
||||
module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
|
||||
sizeof(error_buf));
|
||||
ASSERT_NE(module, nullptr) << "Load module failed: " << error_buf;
|
||||
}
|
||||
|
||||
void instantiate_module()
|
||||
{
|
||||
module_inst = wasm_runtime_instantiate(
|
||||
module, STACK_SIZE, HEAP_SIZE, error_buf, sizeof(error_buf));
|
||||
ASSERT_NE(module_inst, nullptr) << "Instantiate module failed: " << error_buf;
|
||||
|
||||
exec_env = wasm_runtime_create_exec_env(module_inst, STACK_SIZE);
|
||||
ASSERT_NE(exec_env, nullptr);
|
||||
}
|
||||
|
||||
RuntimeInitArgs init_args;
|
||||
wasm_module_t module = nullptr;
|
||||
wasm_module_inst_t module_inst = nullptr;
|
||||
wasm_exec_env_t exec_env = nullptr;
|
||||
unsigned char *wasm_file_buf = nullptr;
|
||||
uint32_t wasm_file_size = 0;
|
||||
char error_buf[128] = { 0 };
|
||||
};
|
||||
|
||||
/**
|
||||
* Test Function 1: call_indirect() - Valid function call
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:call_indirect()
|
||||
* Expected Coverage: ~15 lines (success path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CallIndirect_ValidFunction_ReturnsCorrectResult)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_call_indirect_valid");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 0; // table index 0 (points to $add_func)
|
||||
wasm_argv[1] = 15; // parameter value
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// $add_func adds 10 to input: 15 + 10 = 25
|
||||
ASSERT_EQ(wasm_argv[0], 25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 1: call_indirect() - Invalid index
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:call_indirect()
|
||||
* Expected Coverage: ~15 lines (error path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CallIndirect_InvalidIndex_FailsGracefully)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_call_indirect_invalid_index");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 42; // input value
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
ASSERT_FALSE(success);
|
||||
ASSERT_TRUE(wasm_runtime_get_exception(module_inst) != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 2: wasm_call_indirect() - Type mismatch error handling
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:wasm_call_indirect()
|
||||
* Expected Coverage: ~13 lines (error path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, WasmCallIndirect_TypeMismatch_ReturnsFailure)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_call_indirect_type_mismatch");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 100; // input value
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
ASSERT_FALSE(success);
|
||||
ASSERT_TRUE(wasm_runtime_get_exception(module_inst) != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 3: wasm_interp_call_func_import() - Success path
|
||||
* Target: core/iwasm/interpreter/wasm_interp_fast.c:wasm_interp_call_func_import()
|
||||
* Expected Coverage: ~12 lines (success path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CallFuncImport_Success_CallsNativeFunction)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_import_function_call");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 15; // first parameter
|
||||
wasm_argv[1] = 25; // second parameter
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// test_import_add_impl adds two values: 15 + 25 = 40
|
||||
ASSERT_EQ(wasm_argv[0], 40);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 3: wasm_interp_call_func_import() - Multiple import calls
|
||||
* Target: core/iwasm/interpreter/wasm_interp_fast.c:wasm_interp_call_func_import()
|
||||
* Expected Coverage: ~13 lines (additional path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CallFuncImport_MultipleImports_HandlesCorrectly)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_import_function_mul");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 6; // first parameter
|
||||
wasm_argv[1] = 7; // second parameter
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// test_import_mul_impl multiplies two values: 6 * 7 = 42
|
||||
ASSERT_EQ(wasm_argv[0], 42);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 4: copy_stack_values() - Normal operation
|
||||
* Target: core/iwasm/interpreter/wasm_interp_fast.c:copy_stack_values()
|
||||
* Expected Coverage: ~20 lines (normal operation)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CopyStackValues_Normal_CopiesValuesCorrectly)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_stack_operations");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 10; // val1
|
||||
wasm_argv[1] = 20; // val2
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// Complex calculation: (10+20) + (5+10) + (20*3) = 30 + 15 + 60 = 105
|
||||
ASSERT_EQ(wasm_argv[0], 105);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 4: copy_stack_values() - Large parameter count
|
||||
* Target: core/iwasm/interpreter/wasm_interp_fast.c:copy_stack_values()
|
||||
* Expected Coverage: Additional lines for large stack operations
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, CopyStackValues_LargeParams_HandlesCorrectly)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_large_param_stack");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[8];
|
||||
wasm_argv[0] = 1;
|
||||
wasm_argv[1] = 2;
|
||||
wasm_argv[2] = 3;
|
||||
wasm_argv[3] = 4;
|
||||
wasm_argv[4] = 5;
|
||||
wasm_argv[5] = 6;
|
||||
wasm_argv[6] = 7;
|
||||
wasm_argv[7] = 8;
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 8, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// (1+2) + (3+4) + (5+6) + (7+8) = 3 + 7 + 11 + 15 = 36
|
||||
ASSERT_EQ(wasm_argv[0], 36);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 5: execute_malloc_function() - Success path
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:execute_malloc_function()
|
||||
* Expected Coverage: ~20 lines (success path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, ExecuteMalloc_Success_AllocatesMemory)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_malloc_operation");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 1024; // allocate 1KB
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// Should return a valid memory offset (> 0)
|
||||
ASSERT_GT(wasm_argv[0], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 5: execute_malloc_function() - Failure path
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:execute_malloc_function()
|
||||
* Expected Coverage: ~20 lines (failure path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, ExecuteMalloc_Failure_HandlesLargeAllocation)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_malloc_operation");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 0x10000000; // try to allocate large amount (256MB)
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
// The call should succeed (no crash), but malloc should return 0
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_EQ(wasm_argv[0], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 6: execute_free_function() - Success path
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:execute_free_function()
|
||||
* Expected Coverage: ~20 lines (success path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, ExecuteFree_Success_FreesMemory)
|
||||
{
|
||||
// First allocate memory
|
||||
wasm_function_inst_t malloc_func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_malloc_operation");
|
||||
ASSERT_NE(malloc_func, nullptr);
|
||||
|
||||
uint32_t malloc_argv[1];
|
||||
malloc_argv[0] = 512;
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, malloc_func, 1, malloc_argv);
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_GT(malloc_argv[0], 0);
|
||||
|
||||
// Now free the allocated memory
|
||||
wasm_function_inst_t free_func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_free_operation");
|
||||
ASSERT_NE(free_func, nullptr);
|
||||
|
||||
uint32_t free_argv[1];
|
||||
free_argv[0] = malloc_argv[0]; // use allocated pointer
|
||||
|
||||
success = wasm_runtime_call_wasm(exec_env, free_func, 1, free_argv);
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Function 6: execute_free_function() - Error handling
|
||||
* Target: core/iwasm/interpreter/wasm_runtime.c:execute_free_function()
|
||||
* Expected Coverage: ~20 lines (error path)
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, ExecuteFree_ErrorHandling_HandlesInvalidPointer)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_free_operation");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 0; // try to free NULL pointer
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
ASSERT_TRUE(success); // free(NULL) is valid and should succeed
|
||||
}
|
||||
|
||||
/**
|
||||
* Test malloc/free cycle to exercise both functions together
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, MallocFreeCycle_Complete_WorksCorrectly)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_malloc_free_cycle");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[1];
|
||||
wasm_argv[0] = 256; // allocation size
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 1, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
// Should return the value that was stored (42)
|
||||
ASSERT_EQ(wasm_argv[0], 42);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test complex indirect call scenarios
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, ComplexIndirectCalls_MultipleSelectors_HandlesCorrectly)
|
||||
{
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_complex_indirect_calls");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
// Test selector 0 (add_func)
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 0; // selector
|
||||
wasm_argv[1] = 30; // value
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_EQ(wasm_argv[0], 40); // 30 + 10 = 40
|
||||
|
||||
// Test selector 1 (mul_func)
|
||||
wasm_argv[0] = 1; // selector
|
||||
wasm_argv[1] = 15; // value
|
||||
|
||||
success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_EQ(wasm_argv[0], 30); // 15 * 2 = 30
|
||||
|
||||
// Test selector 2 (identity_func)
|
||||
wasm_argv[0] = 2; // selector
|
||||
wasm_argv[1] = 99; // value
|
||||
|
||||
success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_EQ(wasm_argv[0], 99); // identity returns same value
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional test for function invocation edge cases
|
||||
*/
|
||||
TEST_F(FunctionInvocationTest, FunctionInvocation_EdgeCases_HandlesCorrectly)
|
||||
{
|
||||
// Test with maximum parameter values
|
||||
wasm_function_inst_t func = wasm_runtime_lookup_function(
|
||||
module_inst, "test_stack_operations");
|
||||
ASSERT_NE(func, nullptr);
|
||||
|
||||
uint32_t wasm_argv[2];
|
||||
wasm_argv[0] = 0xFFFFFFFF; // max uint32
|
||||
wasm_argv[1] = 1;
|
||||
|
||||
bool success = wasm_runtime_call_wasm(exec_env, func, 2, wasm_argv);
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,150 +0,0 @@
|
|||
(module
|
||||
;; Import functions
|
||||
(import "env" "test_import_add" (func $test_import_add (param i32 i32) (result i32)))
|
||||
(import "env" "test_import_mul" (func $test_import_mul (param i32 i32) (result i32)))
|
||||
(import "env" "malloc" (func $malloc (param i32) (result i32)))
|
||||
(import "env" "free" (func $free (param i32)))
|
||||
(import "env" "native_func" (func $native_func (param i32) (result i32)))
|
||||
|
||||
;; Type definitions
|
||||
(type $void_to_void (func))
|
||||
(type $i32_to_i32 (func (param i32) (result i32)))
|
||||
(type $i32_i32_to_i32 (func (param i32 i32) (result i32)))
|
||||
|
||||
;; Memory and table
|
||||
(memory 1)
|
||||
(table 4 funcref)
|
||||
|
||||
;; Local functions for table
|
||||
(func $add_func (type $i32_to_i32) (param $x i32) (result i32)
|
||||
local.get $x
|
||||
i32.const 10
|
||||
i32.add)
|
||||
|
||||
(func $mul_func (type $i32_to_i32) (param $x i32) (result i32)
|
||||
local.get $x
|
||||
i32.const 2
|
||||
i32.mul)
|
||||
|
||||
(func $identity_func (type $i32_to_i32) (param $x i32) (result i32)
|
||||
local.get $x)
|
||||
|
||||
(func $void_func (type $void_to_void))
|
||||
|
||||
;; Initialize table
|
||||
(elem (i32.const 0) $add_func $mul_func $identity_func $void_func)
|
||||
|
||||
;; Test functions matching the C++ test expectations
|
||||
(func (export "test_call_indirect_valid") (param $idx i32) (param $val i32) (result i32)
|
||||
local.get $val
|
||||
local.get $idx
|
||||
call_indirect (type $i32_to_i32))
|
||||
|
||||
(func (export "test_call_indirect_invalid_index") (param $val i32) (result i32)
|
||||
local.get $val
|
||||
i32.const 10
|
||||
call_indirect (type $i32_to_i32))
|
||||
|
||||
(func (export "test_call_indirect_type_mismatch") (param $val i32) (result i32)
|
||||
local.get $val
|
||||
i32.const 3
|
||||
call_indirect (type $i32_to_i32))
|
||||
|
||||
(func (export "test_import_function_call") (param $a i32) (param $b i32) (result i32)
|
||||
local.get $a
|
||||
local.get $b
|
||||
call $test_import_add)
|
||||
|
||||
(func (export "test_import_function_mul") (param $a i32) (param $b i32) (result i32)
|
||||
local.get $a
|
||||
local.get $b
|
||||
call $test_import_mul)
|
||||
|
||||
(func (export "test_native_function_call") (param $a i32) (result i32)
|
||||
local.get $a
|
||||
call $native_func)
|
||||
|
||||
(func (export "test_malloc_operation") (param $size i32) (result i32)
|
||||
local.get $size
|
||||
call $malloc)
|
||||
|
||||
(func (export "test_free_operation") (param $ptr i32)
|
||||
local.get $ptr
|
||||
call $free)
|
||||
|
||||
(func (export "test_malloc_free_cycle") (param $size i32) (result i32)
|
||||
(local $ptr i32)
|
||||
local.get $size
|
||||
call $malloc
|
||||
local.set $ptr
|
||||
|
||||
local.get $ptr
|
||||
i32.const 42
|
||||
i32.store
|
||||
|
||||
local.get $ptr
|
||||
i32.load
|
||||
|
||||
local.get $ptr
|
||||
call $free)
|
||||
|
||||
(func (export "test_stack_operations") (param $val1 i32) (param $val2 i32) (result i32)
|
||||
local.get $val1
|
||||
local.get $val2
|
||||
call $test_import_add
|
||||
|
||||
i32.const 5
|
||||
call $add_func
|
||||
i32.add
|
||||
|
||||
local.get $val2
|
||||
i32.const 3
|
||||
call $test_import_mul
|
||||
i32.add)
|
||||
|
||||
(func (export "test_complex_indirect_calls") (param $selector i32) (param $value i32) (result i32)
|
||||
local.get $selector
|
||||
i32.const 0
|
||||
i32.eq
|
||||
if (result i32)
|
||||
local.get $value
|
||||
i32.const 0
|
||||
call_indirect (type $i32_to_i32)
|
||||
else
|
||||
local.get $selector
|
||||
i32.const 1
|
||||
i32.eq
|
||||
if (result i32)
|
||||
local.get $value
|
||||
i32.const 1
|
||||
call_indirect (type $i32_to_i32)
|
||||
else
|
||||
local.get $value
|
||||
i32.const 2
|
||||
call_indirect (type $i32_to_i32)
|
||||
end
|
||||
end)
|
||||
|
||||
(func (export "test_large_param_stack")
|
||||
(param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32)
|
||||
(param $p5 i32) (param $p6 i32) (param $p7 i32) (param $p8 i32)
|
||||
(result i32)
|
||||
local.get $p1
|
||||
local.get $p2
|
||||
call $test_import_add
|
||||
|
||||
local.get $p3
|
||||
local.get $p4
|
||||
call $test_import_add
|
||||
i32.add
|
||||
|
||||
local.get $p5
|
||||
local.get $p6
|
||||
call $test_import_add
|
||||
i32.add
|
||||
|
||||
local.get $p7
|
||||
local.get $p8
|
||||
call $test_import_add
|
||||
i32.add)
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user