Files
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

259 lines
8.3 KiB
Python

# Copyright Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
"""Configuration helper for loading, validation, and logging setup."""
from pathlib import Path
from typing import Optional
from ..logger import log, set_log_level
from .config_parser import ConfigParser
from ..constants import Constants
class ConfigHelper:
"""Configuration helper for file discovery, loading, validation, and logging setup."""
@staticmethod
def find_config_file(
config_file: Optional[str] = None,
default_name: str = Constants.DEFAULT_CONFIG_FILE,
) -> str:
"""Find configuration file in standard locations.
Search order:
1. Provided config_file path (if given)
2. Executor directory (framework parent)
3. Current working directory
4. Return default name (will be created if doesn't exist)
Args:
config_file: Explicit config file path (optional)
default_name: Default config filename to use
Returns:
Path to configuration file
"""
# Use provided path if given
if config_file:
return config_file
# Try executor directory
executor_dir = Path(__file__).parent.parent
config_path = executor_dir / default_name
if config_path.exists():
return str(config_path)
# Try current directory
config_path = Path.cwd() / default_name
if config_path.exists():
return str(config_path)
# Return default name (will be created if doesn't exist)
return default_name
@staticmethod
def load_config(
config_file: str, validate: bool = True, required: bool = False
) -> Optional[ConfigParser]:
"""Load configuration file with error handling.
Args:
config_file: Path to configuration file
validate: Validate configuration against schema
required: Raise exception if config file not found
Returns:
ConfigParser instance or None if file not found and not required
Raises:
FileNotFoundError: If config file not found and required=True
"""
try:
if Path(config_file).exists():
config = ConfigParser(config_file, validate=validate)
log.debug(f"Loaded config: {config_file}")
return config
else:
if required:
raise FileNotFoundError(f"Config file not found: {config_file}")
log.warning(f"Config file not found: {config_file}")
log.warning("Using default configuration")
return None
except Exception as e:
if required:
raise
log.warning(f"Failed to load config: {e}")
log.warning("Using default configuration")
return None
@staticmethod
def configure_logging(config: Optional[ConfigParser], default_level: str = "INFO"):
"""Configure logging from configuration.
Sets log level and optionally enables file logging with rotation.
Args:
config: ConfigParser instance (None = use defaults)
default_level: Default log level if config not available
"""
if not config:
set_log_level(default_level)
return
try:
config_data = config.getConfig()
core_config = config_data.get("Config", {}).get("Core", {})
# Set log level
log_level = core_config.get("LogLevel", default_level)
set_log_level(log_level)
log.debug(f"Log level set to: {log_level}")
# Enable file logging if configured
log_to_file = core_config.get("LogToFile", False)
if log_to_file:
from datetime import datetime
import os
log_dir = core_config.get("LogDirectory", "./logs")
max_size_mb = core_config.get("LogMaxSizeMB", 10)
backup_count = core_config.get("LogBackupCount", 5)
# Create log filename with timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
log_file = os.path.join(log_dir, f"test_executor_{timestamp}.log")
# Enable file logging
from ..logger import setup_file_logging
setup_file_logging(
log_file,
max_bytes=max_size_mb * 1024 * 1024,
backup_count=backup_count,
)
except Exception as e:
log.warning(f"Failed to configure logging: {e}")
log.warning("Using default logging configuration")
@staticmethod
def get_api_config(config: Optional[ConfigParser]) -> dict:
"""Get API configuration from config.
Args:
config: ConfigParser instance
Returns:
Dictionary with API configuration:
- enabled: bool
- url: str
- api_key: str
- timeout: int
- max_retries: int
- retry_delay: int
"""
if not config:
return {
"enabled": False,
"url": "",
"fallback_url": "",
"api_key": "",
"timeout": Constants.DEFAULT_API_TIMEOUT,
"max_retries": Constants.DEFAULT_API_MAX_RETRIES,
"retry_delay": Constants.DEFAULT_API_RETRY_DELAY,
}
try:
config_data = config.getConfig()
core_config = config_data.get("Config", {}).get("Core", {})
api_config = core_config.get("ResultsAPI", {})
return {
"enabled": core_config.get("UploadTestResultsToAPI", False),
"url": api_config.get("URL", ""),
"fallback_url": api_config.get("FallbackURL", ""),
"api_key": api_config.get("APIKey", ""),
"timeout": api_config.get("Timeout", Constants.DEFAULT_API_TIMEOUT),
"max_retries": api_config.get(
"MaxRetries", Constants.DEFAULT_API_MAX_RETRIES
),
"retry_delay": api_config.get(
"RetryDelay", Constants.DEFAULT_API_RETRY_DELAY
),
}
except Exception as e:
log.debug(f"Failed to get API config: {e}")
return {
"enabled": False,
"url": "",
"fallback_url": "",
"api_key": "",
"timeout": Constants.DEFAULT_API_TIMEOUT,
"max_retries": Constants.DEFAULT_API_MAX_RETRIES,
"retry_delay": Constants.DEFAULT_API_RETRY_DELAY,
}
@staticmethod
def get_execution_label(config: Optional[ConfigParser]) -> str:
"""Get execution label from configuration.
Args:
config: ConfigParser instance
Returns:
Execution label string (empty if not configured)
"""
if not config:
return ""
try:
config_data = config.getConfig()
return (
config_data.get("Config", {}).get("Core", {}).get("ExecutionLabel", "")
)
except Exception:
return ""
@staticmethod
def get_ci_group(config: Optional[ConfigParser]) -> str:
"""Get CI group from configuration.
Args:
config: ConfigParser instance
Returns:
CI group string (default: therock_pr)
"""
if not config:
return "therock_pr"
try:
config_data = config.getConfig()
return (
config_data.get("Config", {})
.get("Core", {})
.get("CIGroup", "therock_pr")
)
except Exception:
return "therock_pr"
@staticmethod
def get_deployed_user(config: Optional[ConfigParser]) -> str:
"""Get deployed user from configuration.
Args:
config: ConfigParser instance
Returns:
Deployed user string (empty if not configured)
"""
if not config:
return ""
try:
config_data = config.getConfig()
return config_data.get("Config", {}).get("Core", {}).get("DeployedUser", "")
except Exception:
return ""