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
206 lines
6.8 KiB
Markdown
206 lines
6.8 KiB
Markdown
# Functional Testing Framework
|
|
|
|
Functional tests validate correctness and verify expected behavior without performance measurements.
|
|
|
|
> **Prerequisites:** See [Extended Tests Framework Overview](../README.md) for environment setup, CI/CD integration, and general architecture.
|
|
|
|
## Table of Contents
|
|
|
|
- [Available Tests](#available-tests)
|
|
- [CI Configuration](#ci-configuration)
|
|
- [Project Structure](#project-structure)
|
|
- [How Functional Tests Work](#how-functional-tests-work)
|
|
- [Adding New Functional Tests](#adding-new-functional-tests)
|
|
|
|
## Available Tests
|
|
|
|
| Test Script | Library | Platform | Timeout | Description |
|
|
| --------------------------- | ------- | -------- | ------- | ---------------------------------- |
|
|
| `test_miopendriver_conv.py` | MIOpen | Linux | 30 min | Convolution forward/backward tests |
|
|
|
|
## CI Configuration
|
|
|
|
- **Test Matrix:** See [`functional_test_matrix.py`](functional_test_matrix.py) for complete test definitions (platforms, timeouts, artifacts needed)
|
|
- **Execution:** All functional tests run in nightly CI builds only
|
|
- **Architecture Support:** Tests are architecture-agnostic and support any ROCm-compatible GPU
|
|
- **Architecture Exclusions:** If a specific GPU architecture is not supported for a test, use the `exclude_family` field in the test matrix to skip that architecture/platform combination (see `fetch_test_configurations.py` for filtering logic)
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
functional/
|
|
├── scripts/
|
|
│ ├── functional_base.py # Base class for all functional tests
|
|
│ └── test_miopendriver_conv.py # MIOpen convolution test
|
|
│
|
|
├── configs/
|
|
│ └── miopendriver_conv.json # Test configuration
|
|
│
|
|
├── functional_test_matrix.py # CI test matrix definitions
|
|
└── README.md # This file
|
|
```
|
|
|
|
## How Functional Tests Work
|
|
|
|
### Result Tables
|
|
|
|
Functional tests generate two tables:
|
|
|
|
**Detailed Table:** One row per test case
|
|
|
|
```
|
|
+--------------+--------------------+--------+
|
|
| TestSuite | TestCase | Status |
|
|
+--------------+--------------------+--------+
|
|
| Forward_Conv | Forward_Conv_case1 | PASS |
|
|
| Forward_Conv | Forward_Conv_case2 | PASS |
|
|
+--------------+--------------------+--------+
|
|
```
|
|
|
|
**Summary Table:** Overall statistics
|
|
|
|
```
|
|
+-------------------+-------------------+--------+--------+---------+---------+-------------------+
|
|
| Total TestSuites | Total TestCases | Passed | Failed | Errored | Skipped | Final Result |
|
|
+-------------------+-------------------+--------+--------+---------+---------+-------------------+
|
|
| 2 | 18 | 18 | 0 | 0 | 0 | PASS |
|
|
+-------------------+-------------------+--------+--------+---------+---------+-------------------+
|
|
```
|
|
|
|
## Adding New Functional Tests
|
|
|
|
### 1. Create Test Script
|
|
|
|
Create `scripts/test_your_test.py`:
|
|
|
|
```python
|
|
"""YourTest Functional Test"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[2])) # For utils
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent)) # For functional_base
|
|
from functional_base import FunctionalBase, run_functional_main
|
|
from utils.logger import log
|
|
from utils.exceptions import TestExecutionError
|
|
|
|
|
|
class YourTest(FunctionalBase):
|
|
"""YourTest functional test."""
|
|
|
|
def __init__(self):
|
|
super().__init__(test_name="your_test", display_name="YourTest Functional")
|
|
self.results_json = self.script_dir / "your_test_results.json"
|
|
|
|
# Load test configuration from JSON
|
|
config = self.load_config("your_test.json")
|
|
self.test_cases = config.get("test_cases", [])
|
|
|
|
def run_tests(self) -> None:
|
|
"""Run functional tests and save results to JSON."""
|
|
log.info(f"Running {self.display_name}")
|
|
|
|
# Optional: Get GPU architecture for GPU-specific behavior
|
|
from github_actions_api import get_first_gpu_architecture
|
|
|
|
gfx_id = get_first_gpu_architecture(therock_bin_dir=self.therock_bin_dir)
|
|
|
|
all_results = []
|
|
for test_case in self.test_cases:
|
|
# Execute test, capture result
|
|
status = "PASS" # or "FAIL" based on return code
|
|
all_results.append(
|
|
{
|
|
"test_case": test_case["name"],
|
|
"status": status,
|
|
}
|
|
)
|
|
|
|
# Save results to JSON
|
|
with open(self.results_json, "w") as f:
|
|
json.dump(all_results, f, indent=2)
|
|
|
|
def parse_results(self) -> List[Dict[str, Any]]:
|
|
"""Parse results and return test_results list."""
|
|
log.info("Parsing Results")
|
|
|
|
test_results = []
|
|
|
|
with open(self.results_json, "r") as f:
|
|
json_results = json.load(f)
|
|
|
|
for result in json_results:
|
|
test_results.append(
|
|
self.create_test_result(
|
|
test_name=self.test_name,
|
|
subtest_name=result["test_case"],
|
|
status=result["status"],
|
|
suite=result.get("test_suite", "default"),
|
|
)
|
|
)
|
|
|
|
return test_results
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_functional_main(YourTest())
|
|
```
|
|
|
|
**Required Methods:**
|
|
|
|
- `run_tests()` → Execute tests and save results to JSON
|
|
- `parse_results()` → Returns `List[Dict]` of test results
|
|
- Must use `self.create_test_result(test_name, subtest_name, status, suite, **kwargs)`
|
|
- Status must be: `"PASS"`, `"FAIL"`, `"ERROR"`, or `"SKIP"`
|
|
- Base class generates detailed table and calculates num_suites automatically
|
|
|
|
**Available Helper Methods (inherited from ExtendedTestBase):**
|
|
|
|
- `self.load_config(filename)` → Load JSON config from `configs/` directory
|
|
- `self.execute_command(cmd, env=env)` → Execute command with streaming output
|
|
- `self.create_test_result(...)` → Create standardized result dictionary
|
|
- `self.get_rocm_env()` → Get environment with LD_LIBRARY_PATH for ROCm libraries
|
|
|
|
### 2. Create Configuration File
|
|
|
|
Create `configs/your_test.json`:
|
|
|
|
```json
|
|
{
|
|
"description": "YourTest Configuration",
|
|
"test_cases": [
|
|
{"name": "test_case_1", "command": "..."},
|
|
{"name": "test_case_2", "command": "..."}
|
|
],
|
|
"gpu_specific_flags": {
|
|
"gfx906": {"flags": "-V 0"}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Add to Test Matrix
|
|
|
|
Edit `functional_test_matrix.py`:
|
|
|
|
```python
|
|
"test_your_test": {
|
|
"job_name": "test_your_test",
|
|
"fetch_artifact_args": "--your-lib --tests",
|
|
"timeout_minutes": 30,
|
|
"test_script": f"python {_get_functional_script_path('test_your_test.py')}",
|
|
"platform": ["linux"],
|
|
"total_shards": 1,
|
|
},
|
|
```
|
|
|
|
### 4. Test Locally
|
|
|
|
> **Environment Setup:** See [Extended Tests Framework Overview](../README.md#environment-setup) for required environment variables and setup instructions.
|
|
|
|
```bash
|
|
# Run the test
|
|
python3 tests/extended_tests/functional/scripts/test_your_test.py
|
|
```
|