File indexing completed on 2026-04-27 07:41:41
0001 """
0002 Testbed configuration utilities.
0003
0004 Provides loading and validation of testbed instance configuration (testbed.toml).
0005 """
0006
0007 import tomllib
0008 from pathlib import Path
0009
0010
0011 class TestbedConfigError(Exception):
0012 """Raised when testbed configuration is invalid or missing."""
0013 pass
0014
0015
0016 class TestbedConfig:
0017 """
0018 Testbed instance configuration.
0019
0020 Loads configuration from testbed.toml and provides access to settings.
0021 """
0022
0023 def __init__(self, namespace: str):
0024 """
0025 Initialize with validated namespace.
0026
0027 Args:
0028 namespace: The testbed namespace (must not be empty)
0029 """
0030 self.namespace = namespace
0031
0032 @classmethod
0033 def load(cls, config_path: str) -> 'TestbedConfig':
0034 """
0035 Load testbed configuration from file.
0036
0037 Args:
0038 config_path: Path to config file
0039
0040 Returns:
0041 TestbedConfig instance
0042
0043 Raises:
0044 TestbedConfigError: If config file not found, invalid, or namespace empty
0045 """
0046 config_file = Path(config_path)
0047
0048
0049 if not config_file.exists():
0050 raise TestbedConfigError(
0051 f"Testbed config not found: {config_file}\n"
0052 f"Create testbed.toml with [testbed] section and namespace setting."
0053 )
0054
0055
0056 try:
0057 with open(config_file, 'rb') as f:
0058 config_data = tomllib.load(f)
0059 except tomllib.TOMLDecodeError as e:
0060 raise TestbedConfigError(f"Invalid TOML in {config_file}: {e}")
0061
0062
0063 testbed_section = config_data.get('testbed')
0064 if not testbed_section:
0065 raise TestbedConfigError(
0066 f"Missing [testbed] section in {config_file}"
0067 )
0068
0069
0070 namespace = testbed_section.get('namespace')
0071 if namespace is None:
0072 raise TestbedConfigError(
0073 f"Missing 'namespace' in [testbed] section of {config_file}"
0074 )
0075
0076 if namespace == '':
0077 raise TestbedConfigError(
0078 f"Namespace not configured in {config_file}\n"
0079 f"Edit the file and set namespace to your testbed instance name.\n"
0080 f"Examples: 'epic-fastmon-dev', 'collab-dec29', 'mytest1'"
0081 )
0082
0083 return cls(namespace=namespace)
0084
0085 def __repr__(self) -> str:
0086 return f"TestbedConfig(namespace='{self.namespace}')"
0087
0088
0089 def load_testbed_config(config_path: str) -> TestbedConfig:
0090 """
0091 Load testbed configuration from file.
0092
0093 Args:
0094 config_path: Path to config file
0095
0096 Returns:
0097 TestbedConfig instance
0098
0099 Raises:
0100 TestbedConfigError: If config is missing, invalid, or namespace empty
0101 """
0102 return TestbedConfig.load(config_path=config_path)