mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2026-02-15 15:18:33 +00:00
add AI-generated unit cases for aot module
Signed-off-by: zhenweijin <zhenwei.jin@intel.com> Co-authored-by: ai-assistant
This commit is contained in:
parent
d4034f1cfb
commit
ac90ba082a
|
|
@ -2,3 +2,4 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
add_subdirectory(interpreter)
|
||||
add_subdirectory(aot)
|
||||
|
|
|
|||
71
tests/unit/smart-tests/aot/CMakeLists.txt
Normal file
71
tests/unit/smart-tests/aot/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# 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-tests-aot)
|
||||
|
||||
add_definitions (-DRUN_ON_LINUX)
|
||||
|
||||
add_definitions (-Dattr_container_malloc=malloc)
|
||||
add_definitions (-Dattr_container_free=free)
|
||||
add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
|
||||
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
|
||||
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
|
||||
|
||||
set(WAMR_BUILD_AOT 1)
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_FAST_INTERP 0)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
set(WAMR_BUILD_LIBC_WASI 0)
|
||||
set(WAMR_BUILD_APP_FRAMEWORK 1)
|
||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||
|
||||
include (../../unit_common.cmake)
|
||||
|
||||
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
|
||||
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
|
||||
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
|
||||
endif ()
|
||||
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
|
||||
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
|
||||
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file (GLOB source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
foreach(source ${source_all})
|
||||
string(FIND ${source} "/build/" build_pos)
|
||||
if(build_pos EQUAL -1)
|
||||
list(APPEND UNIT_SOURCE ${source})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set (unit_test_sources
|
||||
${UNIT_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${LIBC_BUILTIN_SOURCE}
|
||||
${IWASM_COMMON_SOURCE}
|
||||
${IWASM_INTERP_SOURCE}
|
||||
${IWASM_AOT_SOURCE}
|
||||
${IWASM_COMPL_SOURCE}
|
||||
)
|
||||
|
||||
# Include GoogleTest module for gtest_discover_tests
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable (smart-tests-aot ${unit_test_sources})
|
||||
|
||||
target_link_libraries (smart-tests-aot ${LLVM_AVAILABLE_LIBS} gtest_main gmock)
|
||||
|
||||
gtest_discover_tests(smart-tests-aot)
|
||||
|
||||
469
tests/unit/smart-tests/aot/enhanced_aot_runtime_test.cc
Normal file
469
tests/unit/smart-tests/aot/enhanced_aot_runtime_test.cc
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include "gtest/gtest.h"
|
||||
#include "wasm_export.h"
|
||||
#include "aot_runtime.h"
|
||||
#include "aot.h"
|
||||
#include "bh_bitmap.h"
|
||||
|
||||
// Enhanced test fixture for aot_runtime.c functions
|
||||
class EnhancedAotRuntimeTest : public testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
ASSERT_TRUE(wasm_runtime_full_init(&init_args));
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
wasm_runtime_destroy();
|
||||
}
|
||||
|
||||
public:
|
||||
char global_heap_buf[512 * 1024];
|
||||
RuntimeInitArgs init_args;
|
||||
};
|
||||
|
||||
/******
|
||||
* Test Case: aot_resolve_import_func_NativeResolutionFails_FallbackResolutionAttempt
|
||||
* Source: core/iwasm/aot/aot_runtime.c:5643-5676
|
||||
* Target Lines: 5643-5676 (fallback resolution via aot_resolve_function_ex)
|
||||
* Functional Purpose: Validates that aot_resolve_import_func() correctly handles
|
||||
* fallback resolution when native symbol resolution fails and
|
||||
* sub-module loading also fails for non-built-in modules.
|
||||
* Call Path: aot_resolve_import_func() <- aot_resolve_symbols() <- module loading
|
||||
* Coverage Goal: Exercise fallback resolution path via aot_resolve_function_ex
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_resolve_import_func_NativeResolutionFails_FallbackResolutionAttempt) {
|
||||
// Create a minimal AOT module for testing
|
||||
AOTModule test_module;
|
||||
memset(&test_module, 0, sizeof(AOTModule));
|
||||
|
||||
// Create test import function that fails native resolution
|
||||
AOTImportFunc import_func;
|
||||
memset(&import_func, 0, sizeof(AOTImportFunc));
|
||||
|
||||
// Set up import function with non-built-in module name
|
||||
import_func.module_name = (char*)"test_module";
|
||||
import_func.func_name = (char*)"test_function";
|
||||
import_func.func_ptr_linked = NULL; // Ensure native resolution fails
|
||||
|
||||
// Create minimal function type
|
||||
AOTFuncType func_type;
|
||||
memset(&func_type, 0, sizeof(AOTFuncType));
|
||||
func_type.param_count = 0;
|
||||
func_type.result_count = 0;
|
||||
import_func.func_type = &func_type;
|
||||
|
||||
// Test the function - this should attempt sub-module loading
|
||||
bool result = aot_resolve_import_func(&test_module, &import_func);
|
||||
|
||||
// The result depends on whether sub-module loading succeeds
|
||||
// Since we're testing with a non-existent module, it should fail gracefully
|
||||
ASSERT_FALSE(result);
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_resolve_symbols_WithUnlinkedFunctions_ResolutionAttempt
|
||||
* Source: core/iwasm/aot/aot_runtime.c:5525-5531
|
||||
* Target Lines: 5525 (function pointer access), 5526 (linked check), 5527 (resolution attempt)
|
||||
* Functional Purpose: Validates that aot_resolve_symbols() correctly iterates through
|
||||
* import functions and attempts resolution for unlinked functions.
|
||||
* Call Path: aot_resolve_symbols() <- wasm_runtime_resolve_symbols() <- public API
|
||||
* Coverage Goal: Exercise basic function iteration and resolution attempt logic
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_resolve_symbols_WithUnlinkedFunctions_ResolutionAttempt) {
|
||||
// Create a minimal AOT module with import functions
|
||||
AOTModule test_module;
|
||||
memset(&test_module, 0, sizeof(AOTModule));
|
||||
|
||||
// Create array of import functions
|
||||
AOTImportFunc import_funcs[2];
|
||||
memset(import_funcs, 0, sizeof(import_funcs));
|
||||
|
||||
// Set up first import function (unlinked)
|
||||
import_funcs[0].module_name = (char*)"test_module1";
|
||||
import_funcs[0].func_name = (char*)"test_function1";
|
||||
import_funcs[0].func_ptr_linked = NULL; // Not linked
|
||||
|
||||
// Create minimal function type for first function
|
||||
AOTFuncType func_type1;
|
||||
memset(&func_type1, 0, sizeof(AOTFuncType));
|
||||
func_type1.param_count = 0;
|
||||
func_type1.result_count = 0;
|
||||
import_funcs[0].func_type = &func_type1;
|
||||
|
||||
// Set up second import function (unlinked)
|
||||
import_funcs[1].module_name = (char*)"test_module2";
|
||||
import_funcs[1].func_name = (char*)"test_function2";
|
||||
import_funcs[1].func_ptr_linked = NULL; // Not linked
|
||||
|
||||
// Create minimal function type for second function
|
||||
AOTFuncType func_type2;
|
||||
memset(&func_type2, 0, sizeof(AOTFuncType));
|
||||
func_type2.param_count = 0;
|
||||
func_type2.result_count = 0;
|
||||
import_funcs[1].func_type = &func_type2;
|
||||
|
||||
// Configure module with import functions
|
||||
test_module.import_funcs = import_funcs;
|
||||
test_module.import_func_count = 2;
|
||||
|
||||
// Test the function - should attempt to resolve both functions
|
||||
bool result = aot_resolve_symbols(&test_module);
|
||||
|
||||
// Should return false since both functions will fail to resolve
|
||||
ASSERT_FALSE(result);
|
||||
|
||||
// Both functions should still be unlinked
|
||||
ASSERT_EQ(import_funcs[0].func_ptr_linked, nullptr);
|
||||
ASSERT_EQ(import_funcs[1].func_ptr_linked, nullptr);
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_const_str_set_insert_FirstInsertion_CreatesHashMapAndInsertsString
|
||||
* Source: core/iwasm/aot/aot_runtime.c:5431-5476
|
||||
* Target Lines: 5437-5448 (hash map creation), 5451-5453 (memory allocation),
|
||||
* 5460-5462 (standard copy), 5469-5476 (insertion and success)
|
||||
* Functional Purpose: Validates that aot_const_str_set_insert() correctly creates
|
||||
* a new hash map when module->const_str_set is NULL and
|
||||
* successfully inserts the first string.
|
||||
* Call Path: Direct call to aot_const_str_set_insert()
|
||||
* Coverage Goal: Exercise hash map creation and first string insertion path
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_const_str_set_insert_FirstInsertion_CreatesHashMapAndInsertsString) {
|
||||
// Create a minimal AOT module for testing
|
||||
AOTModule test_module;
|
||||
memset(&test_module, 0, sizeof(AOTModule));
|
||||
|
||||
// Ensure const_str_set is initially NULL to trigger creation
|
||||
test_module.const_str_set = nullptr;
|
||||
|
||||
// Test string data
|
||||
const char* test_string = "test_function_name";
|
||||
uint32 str_len = strlen(test_string) + 1;
|
||||
char error_buf[256];
|
||||
|
||||
// Call the function under test
|
||||
char* result = aot_const_str_set_insert((const uint8*)test_string, str_len, &test_module,
|
||||
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||
false, // not word-aligned
|
||||
#endif
|
||||
error_buf, sizeof(error_buf));
|
||||
|
||||
// Verify successful insertion
|
||||
ASSERT_NE(nullptr, result);
|
||||
ASSERT_STREQ(test_string, result);
|
||||
|
||||
// Verify hash map was created
|
||||
ASSERT_NE(nullptr, test_module.const_str_set);
|
||||
|
||||
// Cleanup
|
||||
if (test_module.const_str_set) {
|
||||
bh_hash_map_destroy(test_module.const_str_set);
|
||||
}
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_const_str_set_insert_DuplicateString_ReturnsExistingString
|
||||
* Source: core/iwasm/aot/aot_runtime.c:5431-5476
|
||||
* Target Lines: 5464-5467 (hash map lookup and early return)
|
||||
* Functional Purpose: Validates that aot_const_str_set_insert() correctly finds
|
||||
* existing strings in the hash map and returns them without
|
||||
* creating duplicates.
|
||||
* Call Path: Direct call to aot_const_str_set_insert() with existing string
|
||||
* Coverage Goal: Exercise string deduplication logic
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_const_str_set_insert_DuplicateString_ReturnsExistingString) {
|
||||
// Create a minimal AOT module for testing
|
||||
AOTModule test_module;
|
||||
memset(&test_module, 0, sizeof(AOTModule));
|
||||
test_module.const_str_set = nullptr;
|
||||
|
||||
// Test string data
|
||||
const char* test_string = "duplicate_function_name";
|
||||
uint32 str_len = strlen(test_string) + 1;
|
||||
char error_buf[256];
|
||||
|
||||
// First insertion - should create new entry
|
||||
char* first_result = aot_const_str_set_insert((const uint8*)test_string, str_len, &test_module,
|
||||
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||
false,
|
||||
#endif
|
||||
error_buf, sizeof(error_buf));
|
||||
ASSERT_NE(nullptr, first_result);
|
||||
|
||||
// Second insertion of same string - should return existing entry
|
||||
char* second_result = aot_const_str_set_insert((const uint8*)test_string, str_len, &test_module,
|
||||
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||
false,
|
||||
#endif
|
||||
error_buf, sizeof(error_buf));
|
||||
|
||||
// Verify same pointer is returned (deduplication)
|
||||
ASSERT_EQ(first_result, second_result);
|
||||
ASSERT_STREQ(test_string, second_result);
|
||||
|
||||
// Cleanup
|
||||
if (test_module.const_str_set) {
|
||||
bh_hash_map_destroy(test_module.const_str_set);
|
||||
}
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_const_str_set_insert_EmptyString_HandledCorrectly
|
||||
* Source: core/iwasm/aot/aot_runtime.c:5431-5476
|
||||
* Target Lines: 5451-5453 (memory allocation), 5460-5462 (standard copy),
|
||||
* 5469-5476 (insertion and success)
|
||||
* Functional Purpose: Validates that aot_const_str_set_insert() correctly handles
|
||||
* empty strings and edge cases with minimal string data.
|
||||
* Call Path: Direct call to aot_const_str_set_insert() with empty string
|
||||
* Coverage Goal: Exercise edge case handling for minimal string data
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_const_str_set_insert_EmptyString_HandledCorrectly) {
|
||||
// Create a minimal AOT module for testing
|
||||
AOTModule test_module;
|
||||
memset(&test_module, 0, sizeof(AOTModule));
|
||||
test_module.const_str_set = nullptr;
|
||||
|
||||
// Test with null-terminated empty string
|
||||
const char* empty_string = "";
|
||||
uint32 str_len = 1; // Just the null terminator
|
||||
char error_buf[256];
|
||||
|
||||
// Call the function under test
|
||||
char* result = aot_const_str_set_insert((const uint8*)empty_string, str_len, &test_module,
|
||||
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||
false,
|
||||
#endif
|
||||
error_buf, sizeof(error_buf));
|
||||
|
||||
// Verify successful insertion
|
||||
ASSERT_NE(nullptr, result);
|
||||
ASSERT_STREQ(empty_string, result);
|
||||
|
||||
// Verify hash map was created
|
||||
ASSERT_NE(nullptr, test_module.const_str_set);
|
||||
|
||||
// Cleanup
|
||||
if (test_module.const_str_set) {
|
||||
bh_hash_map_destroy(test_module.const_str_set);
|
||||
}
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_memory_init_DroppedSegment_EmptyDataHandling
|
||||
* Source: core/iwasm/aot/aot_runtime.c:3539-3579
|
||||
* Target Lines: 3550-3555 (dropped segment detection and empty data setup)
|
||||
* Functional Purpose: Tests the execution path when data segment has been dropped
|
||||
* (data_dropped bitmap set), ensuring proper handling of empty data
|
||||
* in bulk memory operations.
|
||||
* Call Path: aot_memory_init() <- AOT compiled code <- WebAssembly bulk memory operations
|
||||
* Coverage Goal: Exercise dropped segment handling path for runtime data management
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_memory_init_DroppedSegment_EmptyDataHandling) {
|
||||
// Create AOT module instance with dropped data segment
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
AOTMemoryInstance memory_inst;
|
||||
AOTModule aot_module;
|
||||
AOTMemInitData mem_init_data;
|
||||
AOTMemInitData *mem_init_data_list[1];
|
||||
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
memset(&memory_inst, 0, sizeof(AOTMemoryInstance));
|
||||
memset(&aot_module, 0, sizeof(AOTModule));
|
||||
memset(&mem_init_data, 0, sizeof(AOTMemInitData));
|
||||
|
||||
// Setup module instance structure
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.module = (WASMModule*)&aot_module;
|
||||
module_inst.memory_count = 1;
|
||||
// Allocate array of memory instance pointers
|
||||
module_inst.memories = (WASMMemoryInstance**)wasm_runtime_malloc(sizeof(WASMMemoryInstance*));
|
||||
ASSERT_NE(nullptr, module_inst.memories);
|
||||
module_inst.memories[0] = (WASMMemoryInstance*)&memory_inst;
|
||||
|
||||
// Setup memory instance
|
||||
memory_inst.memory_data_size = 65536;
|
||||
memory_inst.memory_data = (uint8*)wasm_runtime_malloc(memory_inst.memory_data_size);
|
||||
ASSERT_NE(nullptr, memory_inst.memory_data);
|
||||
|
||||
// Setup memory initialization data (will be ignored due to dropped flag)
|
||||
const char test_data[] = "This should be ignored";
|
||||
mem_init_data.byte_count = strlen(test_data);
|
||||
mem_init_data.bytes = (uint8*)test_data;
|
||||
mem_init_data_list[0] = &mem_init_data;
|
||||
|
||||
aot_module.mem_init_data_count = 1;
|
||||
aot_module.mem_init_data_list = mem_init_data_list;
|
||||
|
||||
// Initialize data_dropped bitmap with segment 0 marked as dropped
|
||||
extra.common.data_dropped = bh_bitmap_new(0, 1);
|
||||
ASSERT_NE(nullptr, extra.common.data_dropped);
|
||||
bh_bitmap_set_bit(extra.common.data_dropped, 0); // Mark segment 0 as dropped
|
||||
|
||||
// Test parameters for dropped segment
|
||||
uint32 seg_index = 0;
|
||||
uint32 offset = 0;
|
||||
uint32 len = 10; // Any length should work with dropped segment
|
||||
size_t dst = 1024;
|
||||
|
||||
// Execute aot_memory_init
|
||||
bool result = aot_memory_init(&module_inst, seg_index, offset, len, dst);
|
||||
|
||||
// Assert successful handling of dropped segment (empty data)
|
||||
ASSERT_FALSE(result);
|
||||
|
||||
// Cleanup
|
||||
wasm_runtime_free(memory_inst.memory_data);
|
||||
wasm_runtime_free(module_inst.memories);
|
||||
bh_bitmap_delete(extra.common.data_dropped);
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_memory_init_InvalidAppAddr_ValidationFailure
|
||||
* Source: core/iwasm/aot/aot_runtime.c:3539-3579
|
||||
* Target Lines: 3562-3564 (application address validation failure)
|
||||
* Functional Purpose: Tests the address validation path where wasm_runtime_validate_app_addr
|
||||
* fails due to invalid destination address, ensuring proper error handling
|
||||
* in bulk memory operations.
|
||||
* Call Path: aot_memory_init() <- AOT compiled code <- WebAssembly bulk memory operations
|
||||
* Coverage Goal: Exercise address validation failure path for error handling
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_memory_init_InvalidAppAddr_ValidationFailure) {
|
||||
// Create AOT module instance with invalid destination address
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
AOTMemoryInstance memory_inst;
|
||||
AOTModule aot_module;
|
||||
AOTMemInitData mem_init_data;
|
||||
AOTMemInitData *mem_init_data_list[1];
|
||||
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
memset(&memory_inst, 0, sizeof(AOTMemoryInstance));
|
||||
memset(&aot_module, 0, sizeof(AOTModule));
|
||||
memset(&mem_init_data, 0, sizeof(AOTMemInitData));
|
||||
|
||||
// Setup module instance structure
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.module = (WASMModule*)&aot_module;
|
||||
module_inst.memory_count = 1;
|
||||
// Allocate array of memory instance pointers
|
||||
module_inst.memories = (WASMMemoryInstance**)wasm_runtime_malloc(sizeof(WASMMemoryInstance*));
|
||||
ASSERT_NE(nullptr, module_inst.memories);
|
||||
module_inst.memories[0] = (WASMMemoryInstance*)&memory_inst;
|
||||
|
||||
// Setup memory instance with small memory size
|
||||
memory_inst.memory_data_size = 1024; // Small memory size
|
||||
memory_inst.memory_data = (uint8*)wasm_runtime_malloc(memory_inst.memory_data_size);
|
||||
ASSERT_NE(nullptr, memory_inst.memory_data);
|
||||
|
||||
// Setup valid memory initialization data
|
||||
const char test_data[] = "Test data";
|
||||
mem_init_data.byte_count = strlen(test_data);
|
||||
mem_init_data.bytes = (uint8*)test_data;
|
||||
mem_init_data_list[0] = &mem_init_data;
|
||||
|
||||
aot_module.mem_init_data_count = 1;
|
||||
aot_module.mem_init_data_list = mem_init_data_list;
|
||||
|
||||
// Initialize data_dropped bitmap (not dropped)
|
||||
extra.common.data_dropped = bh_bitmap_new(0, 1);
|
||||
ASSERT_NE(nullptr, extra.common.data_dropped);
|
||||
|
||||
// Test parameters with invalid destination address (beyond memory bounds)
|
||||
uint32 seg_index = 0;
|
||||
uint32 offset = 0;
|
||||
uint32 len = strlen(test_data);
|
||||
size_t dst = memory_inst.memory_data_size + 1000; // Invalid destination beyond memory
|
||||
|
||||
// Execute aot_memory_init
|
||||
bool result = aot_memory_init(&module_inst, seg_index, offset, len, dst);
|
||||
|
||||
// Assert validation failure (wasm_runtime_validate_app_addr fails)
|
||||
ASSERT_FALSE(result);
|
||||
|
||||
// Cleanup
|
||||
wasm_runtime_free(memory_inst.memory_data);
|
||||
wasm_runtime_free(module_inst.memories);
|
||||
bh_bitmap_delete(extra.common.data_dropped);
|
||||
}
|
||||
|
||||
/******
|
||||
* Test Case: aot_memory_init_ZeroLength_EdgeCase
|
||||
* Source: core/iwasm/aot/aot_runtime.c:3579-3614
|
||||
* Target Lines: 3600-3602 (bounds check with len=0), 3608-3614 (memcpy with len=0)
|
||||
* Functional Purpose: Tests the edge case where len=0 is passed to aot_memory_init,
|
||||
* validating correct handling of zero-length memory operations.
|
||||
* Call Path: aot_memory_init() <- AOT compiled code <- WebAssembly bulk memory operations
|
||||
* Coverage Goal: Exercise edge case handling for zero-length memory copy
|
||||
******/
|
||||
TEST_F(EnhancedAotRuntimeTest, aot_memory_init_ZeroLength_EdgeCase) {
|
||||
// Create AOT module instance for zero-length copy test
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
AOTMemoryInstance memory_inst;
|
||||
AOTModule aot_module;
|
||||
AOTMemInitData mem_init_data;
|
||||
AOTMemInitData *mem_init_data_list[1];
|
||||
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
memset(&memory_inst, 0, sizeof(AOTMemoryInstance));
|
||||
memset(&aot_module, 0, sizeof(AOTModule));
|
||||
memset(&mem_init_data, 0, sizeof(AOTMemInitData));
|
||||
|
||||
// Setup module instance structure
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.module = (WASMModule*)&aot_module;
|
||||
module_inst.memory_count = 1;
|
||||
module_inst.memories = (WASMMemoryInstance**)wasm_runtime_malloc(sizeof(WASMMemoryInstance*));
|
||||
ASSERT_NE(nullptr, module_inst.memories);
|
||||
module_inst.memories[0] = (WASMMemoryInstance*)&memory_inst;
|
||||
|
||||
// Setup memory instance with sufficient size
|
||||
memory_inst.memory_data_size = 65536;
|
||||
memory_inst.memory_data = (uint8*)wasm_runtime_malloc(memory_inst.memory_data_size);
|
||||
ASSERT_NE(nullptr, memory_inst.memory_data);
|
||||
|
||||
// Setup memory initialization data
|
||||
const char test_data[] = "Test data for edge case";
|
||||
mem_init_data.byte_count = strlen(test_data);
|
||||
mem_init_data.bytes = (uint8*)test_data;
|
||||
mem_init_data_list[0] = &mem_init_data;
|
||||
|
||||
aot_module.mem_init_data_count = 1;
|
||||
aot_module.mem_init_data_list = mem_init_data_list;
|
||||
|
||||
// Initialize data_dropped bitmap (not dropped)
|
||||
extra.common.data_dropped = bh_bitmap_new(0, 1);
|
||||
ASSERT_NE(nullptr, extra.common.data_dropped);
|
||||
|
||||
// Test parameters with zero length (edge case)
|
||||
uint32 seg_index = 0;
|
||||
uint32 offset = 0;
|
||||
uint32 len = 0; // Zero-length copy
|
||||
size_t dst = 1024;
|
||||
|
||||
// Execute aot_memory_init with zero length
|
||||
bool result = aot_memory_init(&module_inst, seg_index, offset, len, dst);
|
||||
|
||||
// Zero-length copy should succeed (no actual data to copy)
|
||||
ASSERT_TRUE(result);
|
||||
|
||||
// Cleanup
|
||||
wasm_runtime_free(memory_inst.memory_data);
|
||||
wasm_runtime_free(module_inst.memories);
|
||||
bh_bitmap_delete(extra.common.data_dropped);
|
||||
}
|
||||
216
tests/unit/smart-tests/aot/enhanced_gen_aot_test.cc
Normal file
216
tests/unit/smart-tests/aot/enhanced_gen_aot_test.cc
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include "gtest/gtest.h"
|
||||
#include "wasm_export.h"
|
||||
#include "bh_platform.h"
|
||||
#include "aot_llvm.h"
|
||||
#include "aot_intrinsic.h"
|
||||
#include "aot.h"
|
||||
|
||||
#define G_INTRINSIC_COUNT (50u)
|
||||
#define CONS(num) ("f##num##.const")
|
||||
|
||||
// Use external declarations to avoid multiple definitions
|
||||
extern const char *llvm_intrinsic_tmp[G_INTRINSIC_COUNT];
|
||||
extern uint64 g_intrinsic_flag[G_INTRINSIC_COUNT];
|
||||
|
||||
// Enhanced test fixture for coverage improvement
|
||||
class EnhancedAOTTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
virtual void SetUp()
|
||||
{
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
ASSERT_TRUE(wasm_runtime_full_init(&init_args));
|
||||
}
|
||||
|
||||
virtual void TearDown() { wasm_runtime_destroy(); }
|
||||
|
||||
public:
|
||||
char global_heap_buf[512 * 1024];
|
||||
RuntimeInitArgs init_args;
|
||||
};
|
||||
|
||||
// Enhanced test cases targeting set_error_buf_v function coverage
|
||||
// Target: Lines 108-114 in aot_runtime.c set_error_buf_v function
|
||||
|
||||
TEST_F(EnhancedAOTTest, WasmLoader_NullErrorBuffer_HandlesGracefully) {
|
||||
// Tests WASM loader error handling when error_buf is NULL
|
||||
// Path: wasm_runtime_load -> get_package_type -> wasm_loader with NULL buffer
|
||||
|
||||
uint8_t invalid_data[] = {0x00, 0x61, 0x73, 0x6d}; // WASM magic but incomplete
|
||||
uint32_t data_size = sizeof(invalid_data);
|
||||
|
||||
// Load module with NULL error buffer - should handle gracefully without crash
|
||||
wasm_module_t module = wasm_runtime_load(invalid_data, data_size, NULL, 0);
|
||||
ASSERT_EQ(nullptr, module);
|
||||
}
|
||||
|
||||
TEST_F(EnhancedAOTTest, WasmLoader_ValidErrorBuffer_FormatsErrorMessage) {
|
||||
// Tests WASM loader error formatting with valid error buffer
|
||||
// Path: wasm_runtime_load -> wasm_loader_set_error_buf -> error formatting
|
||||
|
||||
uint8_t invalid_data[] = {0x00, 0x61, 0x73, 0x6d}; // WASM magic but incomplete
|
||||
uint32_t data_size = sizeof(invalid_data);
|
||||
char error_buf[256];
|
||||
memset(error_buf, 0, sizeof(error_buf));
|
||||
|
||||
// Load module with valid error buffer - triggers error formatting
|
||||
wasm_module_t module = wasm_runtime_load(invalid_data, data_size, error_buf, sizeof(error_buf));
|
||||
ASSERT_EQ(nullptr, module);
|
||||
|
||||
// Verify error message was generated
|
||||
ASSERT_GT(strlen(error_buf), 0);
|
||||
}
|
||||
|
||||
TEST_F(EnhancedAOTTest, WasmLoader_MalformedData_GeneratesError) {
|
||||
// Tests WASM loader handling of malformed data with large error buffer
|
||||
// Path: wasm_runtime_load -> get_package_type -> validation failure
|
||||
|
||||
// Use malformed data to trigger error handling
|
||||
uint8_t malformed_data[1024];
|
||||
memset(malformed_data, 0xFF, sizeof(malformed_data)); // Fill with invalid data
|
||||
char error_buf[512];
|
||||
memset(error_buf, 0, sizeof(error_buf));
|
||||
|
||||
// This should trigger error handling
|
||||
wasm_module_t module = wasm_runtime_load(malformed_data, sizeof(malformed_data), error_buf, sizeof(error_buf));
|
||||
ASSERT_EQ(nullptr, module);
|
||||
|
||||
// Verify error message was generated
|
||||
ASSERT_GT(strlen(error_buf), 0);
|
||||
}
|
||||
|
||||
TEST_F(EnhancedAOTTest, WasmLoader_MinimalModule_LoadAndInstantiate) {
|
||||
// Tests WASM module loading and instantiation paths
|
||||
// Path: wasm_runtime_load -> wasm_runtime_instantiate
|
||||
|
||||
uint8_t simple_wasm[] = {
|
||||
0x00, 0x61, 0x73, 0x6d, // WASM magic
|
||||
0x01, 0x00, 0x00, 0x00, // WASM version
|
||||
};
|
||||
char error_buf[256];
|
||||
memset(error_buf, 0, sizeof(error_buf));
|
||||
|
||||
wasm_module_t module = wasm_runtime_load(simple_wasm, sizeof(simple_wasm), error_buf, sizeof(error_buf));
|
||||
|
||||
if (module) {
|
||||
// Try to instantiate - may succeed or fail depending on module contents
|
||||
wasm_module_inst_t inst = wasm_runtime_instantiate(module, 8192, 8192, error_buf, sizeof(error_buf));
|
||||
|
||||
if (inst) {
|
||||
wasm_runtime_deinstantiate(inst);
|
||||
}
|
||||
wasm_runtime_unload(module);
|
||||
ASSERT_TRUE(true); // Module loaded successfully
|
||||
} else {
|
||||
// Load failed - verify error message exists
|
||||
ASSERT_GT(strlen(error_buf), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* COMPREHENSIVE COVERAGE TESTS FOR aot_lookup_function_with_idx
|
||||
* TARGET: Lines 1421-1452 in aot_runtime.c
|
||||
*
|
||||
* CALL PATHS EVALUATED:
|
||||
* 1. Direct call to aot_lookup_function_with_idx() [SELECTED - Direct testing]
|
||||
* - Depth: 1 level
|
||||
* - Complexity: LOW (minimal setup required)
|
||||
* - Precision: HIGH (direct targeting of specific lines)
|
||||
* - Rating: ⭐⭐⭐⭐
|
||||
*
|
||||
* 2. aot_get_function_instance() -> aot_lookup_function_with_idx() [Alternative]
|
||||
* - Depth: 2 levels
|
||||
* - Complexity: MEDIUM (requires valid AOT module setup)
|
||||
* - Precision: MEDIUM (additional code paths involved)
|
||||
* - Rating: ⭐⭐⭐
|
||||
*
|
||||
* SELECTED STRATEGY: Use aot_lookup_function_with_idx() directly with crafted AOTModuleInstance
|
||||
* REASON: Most precise targeting of lines 1421-1452 with minimal test complexity
|
||||
*/
|
||||
|
||||
TEST_F(EnhancedAOTTest, LookupFunctionWithIdx_NoExportFunctions_ReturnsNull) {
|
||||
// Target: Line 1418-1419: if (module_inst->export_func_count == 0) return NULL;
|
||||
// This test ensures early return when no export functions exist
|
||||
|
||||
// Create a minimal AOT module instance with no export functions
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.export_func_count = 0; // No export functions
|
||||
|
||||
// Call should return NULL immediately without entering lock section
|
||||
AOTFunctionInstance* result = aot_lookup_function_with_idx(&module_inst, 0);
|
||||
ASSERT_EQ(nullptr, result);
|
||||
}
|
||||
|
||||
TEST_F(EnhancedAOTTest, LookupFunctionWithIdx_MapCreation_FindsViaMapSearch) {
|
||||
// Target: Lines 1421-1452 - Map creation and binary search path
|
||||
// Path: export_func_maps=NULL -> runtime_malloc -> qsort -> bsearch -> found
|
||||
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
AOTFunctionInstance export_funcs[2];
|
||||
|
||||
// Setup module instance with export functions
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
memset(export_funcs, 0, sizeof(export_funcs));
|
||||
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.export_func_count = 2;
|
||||
module_inst.export_functions = (WASMExportFuncInstance*)export_funcs;
|
||||
|
||||
// Setup export function data
|
||||
export_funcs[0].func_index = 100;
|
||||
export_funcs[1].func_index = 200;
|
||||
|
||||
// Ensure export_func_maps is NULL to trigger map creation
|
||||
extra.export_func_maps = NULL;
|
||||
|
||||
// Test finds function via map creation + binary search
|
||||
AOTFunctionInstance* result = aot_lookup_function_with_idx(&module_inst, 100);
|
||||
ASSERT_NE(nullptr, result);
|
||||
ASSERT_EQ(100, result->func_index);
|
||||
}
|
||||
|
||||
TEST_F(EnhancedAOTTest, LookupFunctionWithIdx_BinarySearch_NotFound) {
|
||||
// Target: Binary search not finding function
|
||||
// Path: export_func_maps=NULL -> map creation -> bsearch returns NULL
|
||||
|
||||
AOTModuleInstance module_inst;
|
||||
AOTModuleInstanceExtra extra;
|
||||
AOTFunctionInstance export_funcs[2];
|
||||
|
||||
memset(&module_inst, 0, sizeof(AOTModuleInstance));
|
||||
memset(&extra, 0, sizeof(AOTModuleInstanceExtra));
|
||||
memset(export_funcs, 0, sizeof(export_funcs));
|
||||
|
||||
module_inst.e = (WASMModuleInstanceExtra*)&extra;
|
||||
module_inst.export_func_count = 2;
|
||||
module_inst.export_functions = (WASMExportFuncInstance*)export_funcs;
|
||||
|
||||
export_funcs[0].func_index = 100;
|
||||
export_funcs[1].func_index = 200;
|
||||
|
||||
extra.export_func_maps = NULL; // Triggers map creation
|
||||
|
||||
// Search for non-existent function index - binary search returns NULL
|
||||
AOTFunctionInstance* result = aot_lookup_function_with_idx(&module_inst, 999);
|
||||
ASSERT_EQ(nullptr, result);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user