CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
323 lines
9.7 KiB
Markdown
323 lines
9.7 KiB
Markdown
# ROCm Systems CTest Integration Architecture
|
|
|
|
This directory contains the shared CTest integration files for organizing and executing tests across ROCm system projects using YAML-based test categorization.
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
shared/ctest/
|
|
├── README.md # This file - architecture documentation
|
|
├── TestCategories.cmake # CMake module for test category integration
|
|
└── parse_ctest_categories.py # Python parser for YAML to CMake conversion
|
|
```
|
|
|
|
**Files:**
|
|
- [TestCategories.cmake](./TestCategories.cmake) - CMake module with `apply_ctest_category_labels()` function
|
|
- [parse_ctest_categories.py](./parse_ctest_categories.py) - Python parser for YAML to CMake conversion
|
|
|
|
## Architecture Overview
|
|
|
|
The CTest integration provides a label-based system for organizing **pre-existing CTest tests** into tiered categories. Unlike gtest-filter approaches used in rocm-libraries that create new test targets, this system applies CTest `LABELS` to tests already registered via `add_test()`, enabling flexible filtering with `ctest -L`.
|
|
|
|
### Core Components
|
|
|
|
#### 1. **test_categories.yaml** (Project-specific)
|
|
Located in each project's test directory (e.g., `projects/rocprofiler-compute/tests/test_categories.yaml`).
|
|
|
|
Defines test organization:
|
|
- Test categories with tiered label inheritance
|
|
- Per-category exclusions
|
|
- Custom labels per category
|
|
- Timeout settings
|
|
|
|
#### 2. **parse_ctest_categories.py** (Shared)
|
|
Python script that:
|
|
- Parses YAML configuration files
|
|
- Applies tiered label inheritance (quick → standard → comprehensive → full)(so that a test added for quick category will be executed for other categories as well)
|
|
- Supports exact test name matching and CMake regex patterns
|
|
- Supports matching tests by existing labels (`test_labels`)
|
|
- Generates CMake `set_property()` code to apply labels
|
|
- Deduplicates labels across all tests
|
|
- Optionally appends generated code to an install-time test file
|
|
|
|
#### 3. **TestCategories.cmake** (Shared)
|
|
CMake module providing:
|
|
- `apply_ctest_category_labels()` function for projects
|
|
- Python3 interpreter detection
|
|
- Input validation and error handling
|
|
- Optional `install_test_file` parameter for install-time label support
|
|
|
|
## Execution Flow
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A[Project CMakeLists.txt] -->|"add_test() calls<br/>define tests"| B[Tests Registered in CTest]
|
|
A -->|include| C[TestCategories.cmake]
|
|
A -->|call| D["apply_ctest_category_labels(yaml)"]
|
|
|
|
C -->|find_package| E[Python3]
|
|
D -->|execute_process| F[parse_ctest_categories.py]
|
|
|
|
F -->|read| G[test_categories.yaml]
|
|
F -->|apply| H[Tiered Label Inheritance]
|
|
F -->|generate| I["CMake set_property() Code"]
|
|
|
|
I -->|"file(WRITE)"| J["build/test_categories.cmake"]
|
|
J -->|include| K["Labels Applied to Existing Tests"]
|
|
|
|
B --> K
|
|
K -->|"ctest -L quick"| L[Run Quick Tests]
|
|
K -->|"ctest -L comprehensive"| M[Run Comprehensive Tests]
|
|
|
|
style A fill:#e1f5ff,color:#000
|
|
style F fill:#fff4e1,color:#000
|
|
style J fill:#e8f5e9,color:#000
|
|
style K fill:#f3e5f5,color:#000
|
|
```
|
|
|
|
## Tiered Label Inheritance
|
|
|
|
Categories follow a tiered inheritance model where lower tiers automatically include higher-tier labels:
|
|
|
|
| Category | Labels Applied |
|
|
|----------|---------------|
|
|
| `quick` | `quick`, `standard`, `comprehensive`, `full` |
|
|
| `standard` | `standard`, `comprehensive`, `full` |
|
|
| `comprehensive` | `comprehensive`, `full` |
|
|
| `full` | `full` |
|
|
|
|
This means a test in the `quick` category is also included when running `ctest -L standard`, `ctest -L comprehensive`, or `ctest -L full`. Any custom labels defined in the YAML are appended after the tier labels.
|
|
|
|
## YAML Configuration Format
|
|
|
|
### Basic Structure
|
|
|
|
```yaml
|
|
test_categories:
|
|
category_name:
|
|
description: "Human-readable description"
|
|
test_patterns:
|
|
- test_exact_name # Exact CTest test name
|
|
- test_regex.*pattern # CMake regex pattern (auto-detected)
|
|
test_labels:
|
|
- "existing_label" # Match tests that already have this label
|
|
exclude:
|
|
- test_to_exclude # Applied with "{category}_exclude" label
|
|
labels:
|
|
- "custom_label" # Additional labels beyond tier labels
|
|
|
|
general_exclude:
|
|
exclude_section_name:
|
|
test_patterns:
|
|
- test_to_exclude
|
|
labels:
|
|
- "exclude_label"
|
|
|
|
execution_settings:
|
|
default_timeout: 300
|
|
timeout_multiplier: 1
|
|
category_timeouts:
|
|
quick: 300
|
|
standard: 1800
|
|
comprehensive: 7200
|
|
```
|
|
|
|
### Example (rocprofiler-compute)
|
|
|
|
```yaml
|
|
test_categories:
|
|
quick:
|
|
description: "Fast sanity checks - Run pre-commit (target: < 5 min)"
|
|
test_patterns:
|
|
- test_autogen_config
|
|
- test_roofline_calc_ai_analyze
|
|
- test_utils
|
|
- test_tui_components
|
|
exclude:
|
|
- test_profile_live_attach_detach
|
|
labels:
|
|
- "quick"
|
|
- "pre-commit"
|
|
- "smoke"
|
|
|
|
standard:
|
|
description: "Core functionality - Run on every PR (target: < 30 min)"
|
|
test_patterns:
|
|
- test_autogen_config
|
|
- test_utils
|
|
- test_analyze_workloads
|
|
- test_metric_validation
|
|
exclude:
|
|
- test_profile_live_attach_detach
|
|
labels:
|
|
- "standard"
|
|
- "pr"
|
|
|
|
comprehensive:
|
|
description: "Extended testing - Run nightly (target: < 2 hours)"
|
|
test_patterns:
|
|
- test_profile_dispatch
|
|
- test_profile_kernel_execution
|
|
- test_profile_roofline_1
|
|
# ... all tests
|
|
exclude:
|
|
- test_profile_live_attach_detach
|
|
labels:
|
|
- "comprehensive"
|
|
- "nightly"
|
|
|
|
execution_settings:
|
|
default_timeout: 300
|
|
timeout_multiplier: 1
|
|
category_timeouts:
|
|
quick: 300
|
|
standard: 1800
|
|
comprehensive: 7200
|
|
```
|
|
|
|
### Field Reference
|
|
|
|
| Field | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `test_patterns` | Yes | List of CTest test names or CMake regex patterns to match |
|
|
| `test_labels` | No | List of existing labels to match — tests carrying any of these labels get the category's labels |
|
|
| `exclude` | No | Test names/patterns to tag with `{category}_exclude` label |
|
|
| `labels` | No | Custom labels appended after tier-inherited labels |
|
|
| `description` | No | Human-readable description (ignored by parser) |
|
|
|
|
### Test Matching
|
|
|
|
The parser supports two matching strategies, auto-detected per pattern:
|
|
|
|
**Exact match** — test name contains no regex metacharacters:
|
|
```yaml
|
|
test_patterns:
|
|
- test_utils # Matches the CTest test named exactly "test_utils"
|
|
```
|
|
Generated CMake:
|
|
```cmake
|
|
foreach(_test test_utils)
|
|
if(TEST ${_test})
|
|
set_property(TEST ${_test} APPEND PROPERTY LABELS "quick;standard;comprehensive;full")
|
|
endif()
|
|
endforeach()
|
|
```
|
|
|
|
**Regex match** — test name contains regex metacharacters (`.*+?^${}()|[]\`):
|
|
```yaml
|
|
test_patterns:
|
|
- test_profile_.* # Matches all tests starting with "test_profile_"
|
|
```
|
|
Generated CMake:
|
|
```cmake
|
|
get_property(_all_tests DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY TESTS)
|
|
foreach(_test ${_all_tests})
|
|
if(_test MATCHES "^test_profile_.*$")
|
|
set_property(TEST ${_test} APPEND PROPERTY LABELS "quick;standard;comprehensive;full")
|
|
endif()
|
|
endforeach()
|
|
```
|
|
|
|
### Label-Based Matching (`test_labels`)
|
|
|
|
In addition to matching by test name, categories can match tests by their existing labels:
|
|
|
|
```yaml
|
|
test_categories:
|
|
quick:
|
|
test_labels:
|
|
- "unit" # All tests already labeled "unit" get quick-tier labels
|
|
test_patterns:
|
|
- test_extra_quick
|
|
```
|
|
|
|
This is useful when tests are already labeled in `CMakeLists.txt` via `set_tests_properties()` and you want to include them in a category without listing each name.
|
|
|
|
### General Excludes
|
|
|
|
The `general_exclude` section applies labels directly to test patterns without tier inheritance:
|
|
|
|
```yaml
|
|
general_exclude:
|
|
exclude_flaky:
|
|
test_patterns:
|
|
- test_intermittent_failure
|
|
labels:
|
|
- "flaky"
|
|
- "exclude_flaky"
|
|
```
|
|
|
|
This can be used with `ctest -LE exclude_flaky` to skip these tests.
|
|
|
|
## Integration Guide
|
|
|
|
### Step 1: Create test_categories.yaml
|
|
|
|
Create `test_categories.yaml` in your project's test directory:
|
|
|
|
```
|
|
projects/myproject/tests/test_categories.yaml
|
|
```
|
|
|
|
### Step 2: Include in CMakeLists.txt
|
|
|
|
In your project's CMakeLists.txt, **after** all `add_test()` calls:
|
|
|
|
```cmake
|
|
# Set path to the YAML file
|
|
set(_test_categories_yaml "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_categories.yaml")
|
|
|
|
# Include the shared CTest module
|
|
include(${ROCM_SYSTEMS_ROOT}/shared/ctest/TestCategories.cmake)
|
|
|
|
# Apply category labels to existing tests
|
|
if(EXISTS "${_test_categories_yaml}")
|
|
message(STATUS "YAML-based test categorization")
|
|
apply_ctest_category_labels("${_test_categories_yaml}")
|
|
else()
|
|
message(STATUS "No test categorization (YAML missing)")
|
|
endif()
|
|
```
|
|
|
|
**Important:** `apply_ctest_category_labels()` must be called **after** all `add_test()` calls, since it uses `if(TEST ...)` and `get_property(... PROPERTY TESTS)` to find existing tests.
|
|
|
|
### Step 3: Build and Test
|
|
|
|
```bash
|
|
# Configure
|
|
cmake -B build ..
|
|
|
|
# Run quick sanity checks
|
|
ctest --test-dir build -L quick
|
|
|
|
# Run standard PR tests
|
|
ctest --test-dir build -L standard
|
|
|
|
# Run comprehensive nightly tests
|
|
ctest --test-dir build -L comprehensive
|
|
|
|
# Exclude specific tests
|
|
ctest --test-dir build -L quick -LE quick_exclude
|
|
|
|
# List all tests with their labels
|
|
ctest --test-dir build -N --show-only=json-v1
|
|
|
|
# Verbose output
|
|
ctest --test-dir build -L quick -V
|
|
```
|
|
|
|
### Optional: Install-Time Test File
|
|
|
|
`apply_ctest_category_labels()` accepts an optional second argument to append the generated label code to a file for install-time use:
|
|
|
|
```cmake
|
|
apply_ctest_category_labels(
|
|
"${_test_categories_yaml}"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/install_test_labels.cmake" # appended to this file
|
|
)
|
|
```
|
|
|
|
## Integrations
|
|
|
|
- **rocprofiler-compute** - [test_categories.yaml](../../projects/rocprofiler-compute/tests/test_categories.yaml) | [CMakeLists.txt](../../projects/rocprofiler-compute/CMakeLists.txt)
|