Files
TheRock/rocm-systems/projects/rccl/tools/scripts/test_runner/test_runner.py
T
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

175 lines
6.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
RCCL Test Runner
Main script for executing RCCL unit tests and MPI tests with hierarchical configuration
"""
import sys
import os
import json
import logging
from lib.test_parser import ArgumentParserInterface
from lib.test_config import TestConfigProcessor
from lib.test_executor import TestExecutor, glob_filter_matches
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def main():
"""Main entry point for test runner"""
# Parse command-line arguments
parser_interface = ArgumentParserInterface()
args = parser_interface.process_arguments()
# Validate flag combinations
if args.stop_on_rerun_failure and not args.rerun_failed:
print("ERROR: --stop-on-rerun-failure requires --rerun-failed to be set")
if args.verbose:
print("Exiting: Invalid flag combination")
sys.exit(1)
# Validate config file exists
if not os.path.exists(args.config):
print(f"ERROR: Configuration file not found: {args.config}")
if args.verbose:
print("Exiting: Missing configuration file")
sys.exit(1)
try:
# Load and validate configuration
if args.verbose:
print("Loading configuration...")
config_processor = TestConfigProcessor(args.config)
config_processor.validate_config()
print("Configuration loaded and validated")
# Create test executor
executor = TestExecutor(config_processor, args)
# Check environment
if not executor.check_environment():
if args.verbose:
print("Exiting: Environment check failed")
sys.exit(1)
# Build RCCL (if not --no-build)
if not args.no_build:
if not executor.build_rccl():
print("ERROR: Build failed")
if args.verbose:
print("Exiting: RCCL build failed")
sys.exit(1)
# Build rccl-tests (perf binaries) if the config provides a
# rccl_tests_build_configuration section; no-op otherwise.
if not executor.build_rccl_tests():
print("ERROR: rccl-tests build failed")
if args.verbose:
print("Exiting: rccl-tests build failed")
sys.exit(1)
else:
print("SKIP: Build step skipped (--no-build)")
# Parse and run test suites
if args.skip_tests:
print("SKIP: Test execution skipped (--skip-tests)")
if not args.skip_tests:
if args.verbose:
print("\nParsing test suites...")
test_suites = config_processor.parse_test_suites()
if args.verbose:
print("\nCombined Test Suites (JSON):")
print(json.dumps(test_suites, indent=2))
print()
print(f"Found {len(test_suites)} test suite(s)")
# Print skip messages for disabled or filtered-out test suites upfront.
# --suite-name uses gtest-style glob filtering (see glob_filter_matches).
print()
for suite in test_suites:
suite_name = suite["suite_details"]["name"]
enabled = suite["suite_details"].get("enabled", True)
if not enabled:
print(f"SKIP: Test suite '{suite_name}' is disabled")
elif args.suite_name and not glob_filter_matches(suite_name, args.suite_name):
print(f"SKIP: Test suite '{suite_name}' (does not match --suite-name '{args.suite_name}')")
# Run only enabled (and name-matched) test suites
# Note: Reruns happen immediately within run_test_suite() if --rerun-failed is set
for suite in test_suites:
suite_name = suite["suite_details"]["name"]
enabled = suite["suite_details"].get("enabled", True)
if not enabled:
continue
if args.suite_name and not glob_filter_matches(suite_name, args.suite_name):
continue
executor.run_test_suite(suite)
# Print summary once at the end
executor.print_summary()
# Generate coverage report
if not args.coverage_report:
print("\nSKIP: Coverage report not requested (use --coverage-report to enable)")
executor.generate_coverage_report()
# Emit structured results for the dashboard (no-op unless
# --emit-results / --db-push was passed). Coverage is emitted too when a
# report was generated above.
executor.emit_results()
# Return based on results
if executor.test_results:
from lib.test_executor import TestResult
# Count failures from original run
failed = executor.test_results.count(TestResult.RESULT_FAILED.value)
timeout = executor.test_results.count(TestResult.RESULT_TIMEOUT.value)
# Also check rerun results if any
if executor.rerun_results:
rerun_failed = executor.rerun_results.count(TestResult.RESULT_FAILED.value)
rerun_timeout = executor.rerun_results.count(TestResult.RESULT_TIMEOUT.value)
if rerun_failed > 0 or rerun_timeout > 0:
if args.verbose:
print(f"Exiting: Tests failed after rerun (original: failed={failed}, timeout={timeout}; rerun: failed={rerun_failed}, timeout={rerun_timeout})")
sys.exit(1)
else:
# All reruns passed, but original tests failed - this is a success with caveat
if args.verbose:
print(f"Exiting: All rerun tests passed (original had {failed} failures and {timeout} timeouts, but reruns succeeded)")
sys.exit(0)
elif failed > 0 or timeout > 0:
# No reruns, but original tests failed
if args.verbose:
print(f"Exiting: Tests failed (failed={failed}, timeout={timeout})")
sys.exit(1)
if args.verbose:
print("Exiting: Test run completed successfully")
sys.exit(0)
except KeyboardInterrupt:
print("\n\nInterrupted by user")
if args.verbose:
print("Exiting: User interrupted execution")
sys.exit(130) # Standard exit code for SIGINT
except Exception as e:
print(f"\nERROR: {e}")
if args.verbose:
import traceback
traceback.print_exc()
print("Exiting: Unhandled exception occurred")
sys.exit(1)
if __name__ == "__main__":
main()