This directory contains unit tests for the Level Zero Loader, built using Google Test (gtest) and executed through CMake's CTest framework.
The test suite validates the following components:
- Loader API: Core loader functionality and version queries
- Driver Initialization: Driver discovery, initialization, and ordering
- Validation Layer: Parameter validation and error detection
- Tracing Layer: API call tracing and callback mechanisms
- Multi-Driver Support: Multiple driver scenarios and interactions
- Sysman APIs: System management API conformance
- Handle Translation: Loader handle translation mechanisms
All tests are compiled into a single executable named tests, which includes:
loader_api.cpp- General loader API testsloader_validation_layer.cpp- Validation layer testsloader_tracing_layer.cpp- Tracing layer testsdriver_ordering_helper_tests.cpp- Driver ordering helper functionsdriver_ordering_unit_tests.cpp- Driver ordering logic (static builds on all platforms, or dynamic builds on Linux only)driver_teardown_unit_tests.cpp- Driver teardown logic (static builds on all platforms, or dynamic builds on Linux only)init_driver_unit_tests.cpp- Driver initialization tests (non-Windows only)init_driver_dynamic_unit_tests.cpp- Dynamic driver initialization tests (dynamic builds, non-Windows only)
Different test files are conditionally compiled based on the build configuration:
Static Builds (All Platforms) OR Dynamic Builds (Linux Only):
driver_ordering_unit_tests.cppdriver_teardown_unit_tests.cpp
Non-Windows Only:
init_driver_unit_tests.cpp
Dynamic Build + Non-Windows:
init_driver_dynamic_unit_tests.cpp
These restrictions exist because certain tests require access to internal loader symbols that are not exported in Windows DLLs or depend on platform-specific driver discovery mechanisms.
The test binary should NEVER be run outside of the CTest environment.
CTest automatically sets up the required environment variables, working directories, and driver paths needed for each test. Running the test executable directly (./tests or ./bin/tests) will result in:
- Missing environment configurations
- Incorrect driver paths
- Failed test assertions
- Unreliable test results
Before running CTest, you must set the ZEL_LIBRARY_PATH environment variable to point to where the loader libraries and null drivers are located. This ensures tests can find the required libraries at runtime.
Why ZEL_LIBRARY_PATH?
- Targeted scope: Only affects the Level Zero loader's library search path, not the entire system
- Cross-platform: Works consistently across Linux, Windows, and macOS
- Preferred over
LD_LIBRARY_PATH(Linux) orPATH(Windows) which have broader system-wide effects
Linux/Mac:
export ZEL_LIBRARY_PATH=/path/to/build/lib
# or for current build directory:
export ZEL_LIBRARY_PATH=$PWD/libWindows:
set ZEL_LIBRARY_PATH=C:\path\to\build\bin\Release
# or for current build directory:
set ZEL_LIBRARY_PATH=%CD%\bin\ReleaseExample for typical build directory:
cd build
export ZEL_LIBRARY_PATH=$PWD/lib
ctestWithout this environment variable, tests will fail to locate the loader and driver libraries.
Run all tests:
cd build
export ZEL_LIBRARY_PATH=$PWD/lib # Set library path first
ctestRun tests with verbose output:
ctest --verbose
# or
ctest -VRun a specific test by name:
ctest -R tests_api
ctest -R tests_multi_driver_sortRun tests matching a pattern:
ctest -R "tests_loader_version.*"
ctest -R ".*sysman.*"List all available tests:
ctest -NRun tests in parallel (4 jobs):
ctest -j4Run tests and show only failures:
ctest --output-on-failureTests rely on environment variables to configure the loader behavior. These are automatically set by CTest for each test via the set_property(TEST ... PROPERTY ENVIRONMENT ...) directive in CMakeLists.txt.
| Variable | Purpose | Example Values |
|---|---|---|
ZEL_LIBRARY_PATH |
Required before running CTest. Specifies the path to loader libraries and null drivers | $PWD/lib (Linux), %CD%\bin\Release (Windows) |
| Variable | Purpose | Common Values |
|---|---|---|
ZE_ENABLE_LOADER_DEBUG_TRACE |
Enable debug tracing output from the loader | 1 (enabled) |
ZE_ENABLE_NULL_DRIVER |
Enable the null (test) driver | 1 (enabled) |
ZE_ENABLE_ALT_DRIVERS |
Specify alternative driver paths for multi-driver testing | Comma-separated paths to driver libraries |
ZE_ENABLE_LOADER_DRIVER_DDI_PATH |
Enable DDI extension path support | 1 (enabled) |
| Variable | Purpose | Used In |
|---|---|---|
ZEL_TEST_NULL_DRIVER_TYPE |
Set the type of null driver for testing | GPU, NPU, etc. |
ZEL_TEST_NULL_DRIVER_DISABLE_DDI_EXT |
Disable DDI extension in null driver | 1 (single), 3 (both drivers) |
ZEL_DRIVERS_ORDER |
Specify driver ordering preference | See driver ordering documentation |
ZEL_LOADER_LOGGING_ENABLE_SUCCESS_PRINT |
Enable logging of successful API calls | 1 (enabled) |
set_property(TEST tests_api PROPERTY ENVIRONMENT
"ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")
set_property(TEST tests_multi_driver_sort PROPERTY ENVIRONMENT
"ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_ALT_DRIVERS=/path/to/ze_null_test1.so,/path/to/ze_null_test2.so")Create a new test using Google Test macros in an existing .cpp file or create a new one:
#include "gtest/gtest.h"
#include "ze_api.h"
TEST(MyTestSuite, GivenConditionWhenActionThenExpectedResult) {
// Setup
ze_result_t result;
// Execute
result = zeInit(0);
// Verify
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}If creating a new test file, add it to the test executable:
if(NOT WIN32) # If platform-specific
target_sources(tests PRIVATE my_new_test.cpp)
endif()Add the test to CMakeLists.txt using add_test:
add_test(NAME tests_my_new_feature
COMMAND tests --gtest_filter=*MyTestSuite.GivenConditionWhenActionThenExpectedResult*)
set_property(TEST tests_my_new_feature PROPERTY ENVIRONMENT
"ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")Key points:
- Use a descriptive test name prefixed with
tests_ - Use
--gtest_filterto target specific tests by pattern - Set required environment variables with
set_property - Multiple environment variables are separated by semicolons
cd build
cmake ..
make tests
export ZEL_LIBRARY_PATH=$PWD/lib # Set library path
ctest -R tests_my_new_feature --verboseTests follow the pattern: Given[Context]When[Action]Then[Result]
Examples:
GivenLevelZeroLoaderPresentWhenCallingzeInitThenExpectSuccessGivenMultipleDriversWhenCallingZeInitDriversThenExpectSuccessForZeInitGivenNullPointerWhenCallingzelGetTracingLayerStateThenErrorInvalidNullPointerIsReturned
This convention makes test intent clear and helps with filtering tests by scenario.
Test the loader version query APIs:
tests_loader_version_*
Test driver discovery and initialization:
tests_init_*tests_both_init_*tests_no_initialization
Test scenarios with multiple drivers loaded:
tests_multi_driver_*- Uses
ZE_ENABLE_ALT_DRIVERSto load multiple null drivers
Test the ZEL_DRIVERS_ORDER environment variable:
tests_driver_ordering_*driver_ordering_unit_tests
Test parameter validation and error detection:
tests_event_deadlock- Tests in
loader_validation_layer.cpp
Test API call tracing functionality:
tests_tracing_layer_state_*test_zer_tracing_*
Test System Management API conformance:
tests_single_driver_sysman_*tests_multi_driver_sysman_*
Test loader handle translation mechanisms:
tests_loader_translate_handles_*
cd build
export ZEL_LIBRARY_PATH=$PWD/lib # Set library path first
ctest -R tests_api -VCTest provides various options for debugging and controlling test execution:
# Run with even more verbose output
ctest -VV
# Stop on first failure
ctest --stop-on-failure
# Run only failed tests from last run
ctest --rerun-failed
# Run tests in parallel
ctest -j4
# Show test output only for failures
ctest --output-on-failureNote: Always run tests through CTest. Running the test binary directly is not supported and will lead to unreliable results due to missing environment configurations, incorrect driver paths, and other setup that CTest handles automatically.
The test suite uses "fake" drivers (copies of the null driver with different names) to simulate multiple driver scenarios:
Created during build:
ze_fake_gpu.so/ze_fake_gpu.dll- Simulates a GPU driverze_fake_npu.so/ze_fake_npu.dll- Simulates an NPU driverze_fake_vpu.so/ze_fake_vpu.dll- Simulates a VPU driver
These are automatically copied from the null driver implementations during the test build process.
- Some tests requiring internal symbols are disabled for DLL builds
- Driver paths use backslashes and
.dllextension - Environment variables are set differently (handled by CTest)
- All tests are available for both static and dynamic builds (when appropriate)
- Driver paths use forward slashes and
.soextension - Additional tests for driver discovery mechanisms
Tests are run automatically in CI pipelines on:
- Pull requests
- Commits to main branches
- Release branches
CI runs tests across multiple platforms and configurations to ensure compatibility.
Problem: Tests fail with "driver not found" or "library not found" errors
Solution: Ensure ZEL_LIBRARY_PATH is set before running CTest:
export ZEL_LIBRARY_PATH=$PWD/lib # Linux/Mac
set ZEL_LIBRARY_PATH=%CD%\bin\Release # WindowsAlso verify you're running tests via ctest, not directly.
Problem: Tests pass locally but fail in CI
Solution: Check for platform-specific code or environment assumptions. Ensure tests don't depend on specific hardware.
Problem: New test isn't discovered by CTest
Solution: Verify you've called add_test() in CMakeLists.txt and rebuilt the project.
Problem: Test requires specific environment variable
Solution: Add the variable using set_property(TEST ... PROPERTY ENVIRONMENT ...) in CMakeLists.txt.