Skip to content

Latest commit

 

History

History

README.md

Level Zero Loader Unit Tests

This directory contains unit tests for the Level Zero Loader, built using Google Test (gtest) and executed through CMake's CTest framework.

Overview

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

Test Structure

Test Executable

All tests are compiled into a single executable named tests, which includes:

  • loader_api.cpp - General loader API tests
  • loader_validation_layer.cpp - Validation layer tests
  • loader_tracing_layer.cpp - Tracing layer tests
  • driver_ordering_helper_tests.cpp - Driver ordering helper functions
  • driver_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)

Build Configurations

Different test files are conditionally compiled based on the build configuration:

Static Builds (All Platforms) OR Dynamic Builds (Linux Only):

  • driver_ordering_unit_tests.cpp
  • driver_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.

Running Tests

⚠️ IMPORTANT: Do Not Run Test Binaries Directly

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

Prerequisites: Set ZEL_LIBRARY_PATH

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) or PATH (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/lib

Windows:

set ZEL_LIBRARY_PATH=C:\path\to\build\bin\Release
# or for current build directory:
set ZEL_LIBRARY_PATH=%CD%\bin\Release

Example for typical build directory:

cd build
export ZEL_LIBRARY_PATH=$PWD/lib
ctest

Without this environment variable, tests will fail to locate the loader and driver libraries.

Running Tests via CTest

Run all tests:

cd build
export ZEL_LIBRARY_PATH=$PWD/lib  # Set library path first
ctest

Run tests with verbose output:

ctest --verbose
# or
ctest -V

Run a specific test by name:

ctest -R tests_api
ctest -R tests_multi_driver_sort

Run tests matching a pattern:

ctest -R "tests_loader_version.*"
ctest -R ".*sysman.*"

List all available tests:

ctest -N

Run tests in parallel (4 jobs):

ctest -j4

Run tests and show only failures:

ctest --output-on-failure

Environment Variables Used in Tests

Tests 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.

Required Environment Variable

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)

Core Environment Variables

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)

Test-Specific Environment Variables

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)

Example Environment Setup (Set by CTest)

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")

Adding New Tests

1. Write Test Code

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);
}

2. Add Source File to CMakeLists.txt (if new file)

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()

3. Register Test with CTest

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_filter to target specific tests by pattern
  • Set required environment variables with set_property
  • Multiple environment variables are separated by semicolons

4. Build and Run

cd build
cmake ..
make tests
export ZEL_LIBRARY_PATH=$PWD/lib  # Set library path
ctest -R tests_my_new_feature --verbose

Test Naming Conventions

Tests follow the pattern: Given[Context]When[Action]Then[Result]

Examples:

  • GivenLevelZeroLoaderPresentWhenCallingzeInitThenExpectSuccess
  • GivenMultipleDriversWhenCallingZeInitDriversThenExpectSuccessForZeInit
  • GivenNullPointerWhenCallingzelGetTracingLayerStateThenErrorInvalidNullPointerIsReturned

This convention makes test intent clear and helps with filtering tests by scenario.

Common Test Categories

Loader Version Tests

Test the loader version query APIs:

  • tests_loader_version_*

Driver Initialization Tests

Test driver discovery and initialization:

  • tests_init_*
  • tests_both_init_*
  • tests_no_initialization

Multi-Driver Tests

Test scenarios with multiple drivers loaded:

  • tests_multi_driver_*
  • Uses ZE_ENABLE_ALT_DRIVERS to load multiple null drivers

Driver Ordering Tests

Test the ZEL_DRIVERS_ORDER environment variable:

  • tests_driver_ordering_*
  • driver_ordering_unit_tests

Validation Layer Tests

Test parameter validation and error detection:

  • tests_event_deadlock
  • Tests in loader_validation_layer.cpp

Tracing Layer Tests

Test API call tracing functionality:

  • tests_tracing_layer_state_*
  • test_zer_tracing_*

Sysman API Tests

Test System Management API conformance:

  • tests_single_driver_sysman_*
  • tests_multi_driver_sysman_*

Handle Translation Tests

Test loader handle translation mechanisms:

  • tests_loader_translate_handles_*

Debugging Tests

Run a Single Test with Verbose Output

cd build
export ZEL_LIBRARY_PATH=$PWD/lib  # Set library path first
ctest -R tests_api -V

Use CTest Options for Debugging

CTest 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-failure

Note: 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.

Test Fake Drivers

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 driver
  • ze_fake_npu.so / ze_fake_npu.dll - Simulates an NPU driver
  • ze_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.

Platform-Specific Notes

Windows

  • Some tests requiring internal symbols are disabled for DLL builds
  • Driver paths use backslashes and .dll extension
  • Environment variables are set differently (handled by CTest)

Linux

  • All tests are available for both static and dynamic builds (when appropriate)
  • Driver paths use forward slashes and .so extension
  • Additional tests for driver discovery mechanisms

Continuous Integration

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.

Troubleshooting

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  # Windows

Also 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.

Additional Resources