Skip to content

Commit 12019bd

Browse files
committed
lint
1 parent ef9ec04 commit 12019bd

5 files changed

Lines changed: 87 additions & 71 deletions

File tree

extras/asr-services/tests/test_cuda_version_config.py

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
import os
99
import re
10-
import pytest
1110
from pathlib import Path
1211

12+
import pytest
13+
1314

1415
class TestDockerfileCUDASupport:
1516
"""Test that Dockerfiles support configurable CUDA versions."""
@@ -34,56 +35,63 @@ def test_vibevoice_dockerfile_has_cuda_arg(self, vibevoice_dockerfile_path):
3435
content = vibevoice_dockerfile_path.read_text()
3536

3637
# Should have ARG declaration
37-
assert re.search(r"ARG\s+PYTORCH_CUDA_VERSION", content), \
38-
"Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
38+
assert re.search(
39+
r"ARG\s+PYTORCH_CUDA_VERSION", content
40+
), "Dockerfile must declare PYTORCH_CUDA_VERSION build arg"
3941

4042
# Should have default value
4143
arg_match = re.search(r"ARG\s+PYTORCH_CUDA_VERSION=(\w+)", content)
4244
assert arg_match, "PYTORCH_CUDA_VERSION should have default value"
4345
default_version = arg_match.group(1)
44-
assert default_version in ["cu121", "cu126", "cu128"], \
45-
f"Default CUDA version {default_version} should be cu121, cu126, or cu128"
46-
47-
def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync(self, vibevoice_dockerfile_path):
46+
assert default_version in [
47+
"cu121",
48+
"cu126",
49+
"cu128",
50+
], f"Default CUDA version {default_version} should be cu121, cu126, or cu128"
51+
52+
def test_vibevoice_dockerfile_uses_cuda_arg_in_uv_sync(
53+
self, vibevoice_dockerfile_path
54+
):
4855
"""Test that VibeVoice Dockerfile uses CUDA arg in uv sync command."""
4956
content = vibevoice_dockerfile_path.read_text()
5057

5158
# Should use --extra ${PYTORCH_CUDA_VERSION}
52-
assert re.search(r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content), \
53-
"uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
59+
assert re.search(
60+
r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content
61+
), "uv sync command must include --extra ${PYTORCH_CUDA_VERSION}"
5462

5563
def test_nemo_dockerfile_has_cuda_support(self, nemo_dockerfile_path):
5664
"""Test that NeMo Dockerfile (reference implementation) has CUDA support."""
5765
content = nemo_dockerfile_path.read_text()
5866

59-
assert re.search(r"ARG\s+PYTORCH_CUDA_VERSION", content), \
60-
"NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
67+
assert re.search(
68+
r"ARG\s+PYTORCH_CUDA_VERSION", content
69+
), "NeMo Dockerfile should have PYTORCH_CUDA_VERSION arg"
6170

62-
assert re.search(r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content), \
63-
"NeMo Dockerfile should use CUDA version in uv sync"
71+
assert re.search(
72+
r"uv\s+sync.*--extra\s+\$\{PYTORCH_CUDA_VERSION\}", content
73+
), "NeMo Dockerfile should use CUDA version in uv sync"
6474

6575
def test_docker_compose_passes_cuda_arg_to_vibevoice(self, docker_compose_path):
6676
"""Test that docker-compose.yml passes PYTORCH_CUDA_VERSION to vibevoice service."""
6777
content = docker_compose_path.read_text()
6878

6979
# Find vibevoice-asr service section
7080
vibevoice_section = re.search(
71-
r"vibevoice-asr:.*?(?=^\S|\Z)",
72-
content,
73-
re.MULTILINE | re.DOTALL
81+
r"vibevoice-asr:.*?(?=^\S|\Z)", content, re.MULTILINE | re.DOTALL
7482
)
7583
assert vibevoice_section, "docker-compose.yml must have vibevoice-asr service"
7684

7785
section_text = vibevoice_section.group(0)
7886

7987
# Should have build args section
80-
assert re.search(r"args:", section_text), \
81-
"vibevoice-asr service should have build args section"
88+
assert re.search(
89+
r"args:", section_text
90+
), "vibevoice-asr service should have build args section"
8291

8392
# Should pass PYTORCH_CUDA_VERSION
8493
assert re.search(
85-
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}",
86-
section_text
94+
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu126\}", section_text
8795
), "vibevoice-asr should pass PYTORCH_CUDA_VERSION build arg with cu126 default"
8896

8997
def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
@@ -95,9 +103,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
95103

96104
for service_name in gpu_services:
97105
service_match = re.search(
98-
rf"{service_name}:.*?(?=^\S|\Z)",
99-
content,
100-
re.MULTILINE | re.DOTALL
106+
rf"{service_name}:.*?(?=^\S|\Z)", content, re.MULTILINE | re.DOTALL
101107
)
102108

103109
if service_match:
@@ -108,7 +114,7 @@ def test_docker_compose_cuda_arg_consistency(self, docker_compose_path):
108114
# Should have PYTORCH_CUDA_VERSION arg
109115
assert re.search(
110116
r"PYTORCH_CUDA_VERSION:\s*\$\{PYTORCH_CUDA_VERSION:-cu\d+\}",
111-
service_text
117+
service_text,
112118
), f"{service_name} with GPU should have PYTORCH_CUDA_VERSION build arg"
113119

114120

@@ -120,8 +126,9 @@ def test_cuda_version_env_var_format(self):
120126
valid_versions = ["cu121", "cu126", "cu128"]
121127

122128
for version in valid_versions:
123-
assert re.match(r"^cu\d{3}$", version), \
124-
f"{version} should match pattern cu### (e.g., cu121, cu126)"
129+
assert re.match(
130+
r"^cu\d{3}$", version
131+
), f"{version} should match pattern cu### (e.g., cu121, cu126)"
125132

126133
def test_cuda_version_from_env(self):
127134
"""Test reading CUDA version from environment."""
@@ -161,22 +168,26 @@ def test_rtx_5090_requires_cu128(self):
161168
# Map GPU architecture to minimum CUDA version
162169
arch_to_cuda = {
163170
"sm_120": "cu128", # RTX 5090, RTX 50 series
164-
"sm_90": "cu126", # RTX 4090, H100
165-
"sm_89": "cu121", # RTX 4090
166-
"sm_86": "cu121", # RTX 3090, A6000
171+
"sm_90": "cu126", # RTX 4090, H100
172+
"sm_89": "cu121", # RTX 4090
173+
"sm_86": "cu121", # RTX 3090, A6000
167174
}
168175

169-
assert arch_to_cuda.get(gpu_arch) == required_cuda, \
170-
f"GPU architecture {gpu_arch} requires CUDA version {required_cuda}"
176+
assert (
177+
arch_to_cuda.get(gpu_arch) == required_cuda
178+
), f"GPU architecture {gpu_arch} requires CUDA version {required_cuda}"
171179

172180
def test_older_gpus_work_with_cu121(self):
173181
"""Test that older GPUs (sm_86, sm_80) work with cu121."""
174182
older_archs = ["sm_86", "sm_80", "sm_75"] # RTX 3090, A100, RTX 2080
175183

176184
for arch in older_archs:
177185
# cu121 supports these architectures
178-
assert arch in ["sm_75", "sm_80", "sm_86"], \
179-
f"{arch} should be supported by CUDA 12.1"
186+
assert arch in [
187+
"sm_75",
188+
"sm_80",
189+
"sm_86",
190+
], f"{arch} should be supported by CUDA 12.1"
180191

181192

182193
class TestPyProjectCUDAExtras:
@@ -199,8 +210,9 @@ def test_pyproject_has_cuda_extras(self, pyproject_path):
199210

200211
for version in cuda_versions:
201212
# Look for the CUDA version as an extra
202-
assert re.search(rf'["\']?{version}["\']?\s*=', content), \
203-
f"pyproject.toml should define {version} extra"
213+
assert re.search(
214+
rf'["\']?{version}["\']?\s*=', content
215+
), f"pyproject.toml should define {version} extra"
204216

205217
def test_pyproject_cuda_extras_have_pytorch(self, pyproject_path):
206218
"""Test that CUDA extras include torch/torchaudio dependencies."""
@@ -211,9 +223,9 @@ def test_pyproject_cuda_extras_have_pytorch(self, pyproject_path):
211223

212224
# Each CUDA extra should reference torch with the appropriate index
213225
# e.g., { extra = "cu128" } or { index = "pytorch-cu128" }
214-
assert re.search(r'extra\s*=\s*["\']cu\d{3}["\']', content) or \
215-
re.search(r'index\s*=\s*["\']pytorch-cu\d{3}["\']', content), \
216-
"CUDA extras should reference PyTorch with CUDA version"
226+
assert re.search(r'extra\s*=\s*["\']cu\d{3}["\']', content) or re.search(
227+
r'index\s*=\s*["\']pytorch-cu\d{3}["\']', content
228+
), "CUDA extras should reference PyTorch with CUDA version"
217229

218230

219231
if __name__ == "__main__":

tests/configuration/test_llm_custom_provider.robot

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Setup Temp Config
1111
${random_suffix}= Generate Random String 8 [NUMBERS]
1212
${temp_path}= Join Path ${OUTPUT DIR} temp_config_${random_suffix}
1313
Create Directory ${temp_path}
14-
14+
1515
# Create initial default config content
1616
${defaults}= Create Dictionary llm=openai-llm embedding=openai-embed stt=stt-deepgram
1717
${model1_params}= Create Dictionary temperature=${0.2} max_tokens=${2000}
@@ -73,7 +73,7 @@ Add New Model To Config
7373

7474
${config}= Call Method ${cm} get_full_config
7575
${models}= Get From Dictionary ${config} models
76-
76+
7777
${target_model}= Set Variable ${None}
7878
FOR ${m} IN @{models}
7979
Run Keyword If '${m["name"]}' == 'custom-llm' Set Test Variable ${target_model} ${m}
@@ -101,7 +101,7 @@ Update Existing Model
101101

102102
${config}= Call Method ${cm} get_full_config
103103
${models}= Get From Dictionary ${config} models
104-
104+
105105
${count}= Set Variable 0
106106
${target_model}= Set Variable ${None}
107107
FOR ${m} IN @{models}
@@ -245,14 +245,14 @@ Existing Models Preserved After Adding Custom
245245
${models_after}= Get From Dictionary ${config_after} models
246246
${new_count}= Get Length ${models_after}
247247
${expected_count}= Evaluate ${original_count} + 1
248-
248+
249249
Should Be Equal As Integers ${new_count} ${expected_count}
250250

251251
${model_names}= Create List
252252
FOR ${m} IN @{models_after}
253253
Append To List ${model_names} ${m["name"]}
254254
END
255-
255+
256256
List Should Contain Value ${model_names} openai-llm
257257
List Should Contain Value ${model_names} local-embed
258-
List Should Contain Value ${model_names} custom-llm
258+
List Should Contain Value ${model_names} custom-llm

tests/configuration/test_transcription_url.robot

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Vibevoice Url Without Http Prefix
88
[Documentation] Test that VIBEVOICE_ASR_URL without http:// prefix works correctly.
99
${config_template}= Create Dictionary model_url=http://\${oc.env:VIBEVOICE_ASR_URL,host.docker.internal:8767}
1010
${env_vars}= Create Dictionary VIBEVOICE_ASR_URL=host.docker.internal:8767
11-
11+
1212
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
1313
Should Be Equal ${resolved["model_url"]} http://host.docker.internal:8767
1414
Should Not Contain ${resolved["model_url"]} http://http://
@@ -17,7 +17,7 @@ Vibevoice Url With Http Prefix Causes Double Prefix
1717
[Documentation] Test that VIBEVOICE_ASR_URL WITH http:// causes double prefix (bug scenario).
1818
${config_template}= Create Dictionary model_url=http://\${oc.env:VIBEVOICE_ASR_URL,host.docker.internal:8767}
1919
${env_vars}= Create Dictionary VIBEVOICE_ASR_URL=http://host.docker.internal:8767
20-
20+
2121
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
2222
Should Be Equal ${resolved["model_url"]} http://http://host.docker.internal:8767
2323
Should Contain ${resolved["model_url"]} http://http://
@@ -26,22 +26,22 @@ Vibevoice Url Default Fallback
2626
[Documentation] Test that default fallback works when VIBEVOICE_ASR_URL is not set.
2727
${config_template}= Create Dictionary model_url=http://\${oc.env:VIBEVOICE_ASR_URL,host.docker.internal:8767}
2828
${env_vars}= Create Dictionary
29-
29+
3030
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
3131
Should Be Equal ${resolved["model_url"]} http://host.docker.internal:8767
3232

3333
Parakeet Url Configuration
3434
[Documentation] Test that PARAKEET_ASR_URL follows same pattern.
3535
${config_template}= Create Dictionary model_url=http://\${oc.env:PARAKEET_ASR_URL,172.17.0.1:8767}
3636
${env_vars}= Create Dictionary PARAKEET_ASR_URL=host.docker.internal:8767
37-
37+
3838
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
3939
Should Be Equal ${resolved["model_url"]} http://host.docker.internal:8767
4040
Should Not Contain ${resolved["model_url"]} http://http://
4141

4242
Url Parsing Removes Double Slashes
4343
[Documentation] Test that URL with double http:// causes connection failures (simulated by parsing check).
44-
44+
4545
# Valid URL
4646
${valid_url}= Set Variable http://host.docker.internal:8767/transcribe
4747
${parsed_valid}= Check Url Parsing ${valid_url}
@@ -62,7 +62,7 @@ Use Provider Segments Default False
6262
${backend}= Create Dictionary transcription=${transcription}
6363
${config_template}= Create Dictionary backend=${backend}
6464
${env_vars}= Create Dictionary
65-
65+
6666
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
6767
${val}= Evaluate $resolved.get('backend', {}).get('transcription', {}).get('use_provider_segments', False)
6868
Should Be Equal ${val} ${FALSE}
@@ -94,13 +94,13 @@ Model Registry Url Resolution With Env Var
9494
... model_type=stt
9595
... model_provider=vibevoice
9696
... model_url=http://\${oc.env:VIBEVOICE_ASR_URL,host.docker.internal:8767}
97-
97+
9898
${models}= Create List ${model_def}
9999
${defaults}= Create Dictionary stt=stt-vibevoice
100100
${config_template}= Create Dictionary defaults=${defaults} models=${models}
101-
101+
102102
${env_vars}= Create Dictionary VIBEVOICE_ASR_URL=host.docker.internal:8767
103-
103+
104104
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
105105
${resolved_models}= Get From Dictionary ${resolved} models
106106
Should Be Equal ${resolved_models[0]["model_url"]} http://host.docker.internal:8767
@@ -110,17 +110,17 @@ Multiple Asr Providers Url Resolution
110110
${m1}= Create Dictionary name=stt-vibevoice model_url=http://\${oc.env:VIBEVOICE_ASR_URL,host.docker.internal:8767}
111111
${m2}= Create Dictionary name=stt-parakeet model_url=http://\${oc.env:PARAKEET_ASR_URL,172.17.0.1:8767}
112112
${m3}= Create Dictionary name=stt-deepgram model_url=https://api.deepgram.com/v1
113-
113+
114114
${models}= Create List ${m1} ${m2} ${m3}
115115
${config_template}= Create Dictionary models=${models}
116-
116+
117117
${env_vars}= Create Dictionary
118118
... VIBEVOICE_ASR_URL=host.docker.internal:8767
119119
... PARAKEET_ASR_URL=localhost:8080
120-
120+
121121
${resolved}= Resolve Omega Config ${config_template} ${env_vars}
122122
${resolved_models}= Get From Dictionary ${resolved} models
123-
123+
124124
Should Be Equal ${resolved_models[0]["model_url"]} http://host.docker.internal:8767
125125
Should Be Equal ${resolved_models[1]["model_url"]} http://localhost:8080
126126
Should Be Equal ${resolved_models[2]["model_url"]} https://api.deepgram.com/v1

tests/libs/ConfigTestHelper.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import os
22
import sys
3-
import yaml
43
from pathlib import Path
5-
from typing import Dict, Any, Optional, List
6-
from omegaconf import OmegaConf
4+
from typing import Any, Dict, List, Optional
75
from unittest.mock import patch
86

7+
import yaml
8+
from omegaconf import OmegaConf
9+
910
# Add repo root to path to import config_manager
1011
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
1112
from config_manager import ConfigManager
1213

14+
1315
class ConfigTestHelper:
1416
"""Helper library for testing configuration logic."""
1517

@@ -21,14 +23,16 @@ def _to_dict(self, obj: Any) -> Any:
2123
return [self._to_dict(v) for v in obj]
2224
return obj
2325

24-
def resolve_omega_config(self, config_template: Dict[str, Any], env_vars: Dict[str, str]) -> Dict[str, Any]:
26+
def resolve_omega_config(
27+
self, config_template: Dict[str, Any], env_vars: Dict[str, str]
28+
) -> Dict[str, Any]:
2529
"""
2630
Resolves an OmegaConf configuration template with provided environment variables.
2731
"""
2832
config_template = self._to_dict(config_template)
2933
# We need to ensure values are strings for os.environ
3034
str_env_vars = {k: str(v) for k, v in env_vars.items()}
31-
35+
3236
with patch.dict(os.environ, str_env_vars):
3337
conf = OmegaConf.create(config_template)
3438
resolved = OmegaConf.to_container(conf, resolve=True)
@@ -39,14 +43,13 @@ def check_url_parsing(self, url: str) -> Dict[str, Any]:
3943
Parses a URL and returns its components to verify correct parsing.
4044
"""
4145
from urllib.parse import urlparse
46+
4247
parsed = urlparse(url)
43-
return {
44-
"scheme": parsed.scheme,
45-
"netloc": parsed.netloc,
46-
"path": parsed.path
47-
}
48+
return {"scheme": parsed.scheme, "netloc": parsed.netloc, "path": parsed.path}
4849

49-
def create_temp_config_structure(self, base_path: str, content: Dict[str, Any]) -> str:
50+
def create_temp_config_structure(
51+
self, base_path: str, content: Dict[str, Any]
52+
) -> str:
5053
"""
5154
Creates the config folder structure and config.yml within the given base path.
5255
"""
@@ -67,7 +70,9 @@ def add_model_to_config_manager(self, cm: ConfigManager, model_def: Dict[str, An
6770
model_def = self._to_dict(model_def)
6871
cm.add_or_update_model(model_def)
6972

70-
def update_defaults_in_config_manager(self, cm: ConfigManager, updates: Dict[str, str]):
73+
def update_defaults_in_config_manager(
74+
self, cm: ConfigManager, updates: Dict[str, str]
75+
):
7176
"""Wrapper for update_config_defaults that converts arguments."""
7277
updates = self._to_dict(updates)
73-
cm.update_config_defaults(updates)
78+
cm.update_config_defaults(updates)

0 commit comments

Comments
 (0)