style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 52s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 56s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m22s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m10s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 2m18s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 2m36s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m11s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 5m12s
AI Code Review / AI Code Review (pull_request) Successful in 6m49s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 13m15s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 2s
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m41s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 33s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 35s

This commit is contained in:
CI Bot
2026-09-27 06:34:51 +00:00
parent dc10f32124
commit 5e045a14f6
2 changed files with 29 additions and 28 deletions
+23 -25
View File
@@ -129,9 +129,7 @@ class TestPostSync:
body = {"status": "failed", "ffmpeg_rc": 1, "message": "Invalid data"}
with mock.patch("urllib.request.urlopen", return_value=_fake_response(body=body)):
with pytest.raises(GpuEncodeError, match="rc=1"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
def test_http_4xx_raises(self, client):
err = urllib.error.HTTPError(
@@ -139,37 +137,27 @@ class TestPostSync:
)
with mock.patch("urllib.request.urlopen", side_effect=err):
with pytest.raises(GpuEncodeError, match="HTTP 422"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
def test_connection_error_raises(self, client):
with mock.patch("urllib.request.urlopen", side_effect=urllib.error.URLError("conn refused")):
with pytest.raises(GpuEncodeError, match="connection error"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
def test_timeout_error_raises(self, client):
with mock.patch("urllib.request.urlopen", side_effect=socket.timeout("timed out")):
with pytest.raises(GpuEncodeError, match="connection error"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
def test_bad_json_raises(self, client):
with mock.patch("urllib.request.urlopen", return_value=_fake_response(body=b"not-json")):
with pytest.raises(GpuEncodeError, match="bad JSON"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
def test_uploaded_false_logs_warning_but_succeeds(self, client, caplog):
body = {"status": "completed", "ffmpeg_rc": 0, "uploaded": False, "job_id": "j"}
with mock.patch("urllib.request.urlopen", return_value=_fake_response(body=body)), caplog.at_level("WARNING"):
res = client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}
)
res = client._post_sync({"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10})
assert res["status"] == "completed"
assert "uploaded=false" in caplog.text
@@ -192,8 +180,10 @@ class TestRelayUrl:
def test_result_get_url_falls_back_to_external_when_not_set(self):
c = GpuEncoderClient(
endpoint="http://gpu", relay_base_url="http://api.example.com",
relay_secret="s", mezzanine_transport="oss",
endpoint="http://gpu",
relay_base_url="http://api.example.com",
relay_secret="s",
mezzanine_transport="oss",
)
put = c._result_put_url("k", "s")
get = c._result_get_url("k", "s")
@@ -516,7 +506,6 @@ class TestOssHelpers:
svc.delete_file.assert_called_once_with("k")
# ── encode_mezzanine_to_output: relay transport (default path) ──────
class TestEncodeMezzanineRelay:
def test_relay_happy_path_uploads_to_relay(self, tmp_path):
@@ -535,9 +524,16 @@ class TestEncodeMezzanineRelay:
with (
mock.patch.object(c, "_upload_file_put") as m_put,
mock.patch.object(
c, "_post_sync",
return_value={"job_id": "j", "status": "completed", "ffmpeg_rc": 0,
"uploaded": True, "size": 100, "duration": 1.0},
c,
"_post_sync",
return_value={
"job_id": "j",
"status": "completed",
"ffmpeg_rc": 0,
"uploaded": True,
"size": 100,
"duration": 1.0,
},
) as m_post,
mock.patch.object(c, "_download_to_file", return_value=100),
mock.patch.object(c, "_relay_delete") as m_del,
@@ -575,7 +571,8 @@ class TestEncodeMezzanineRelay:
mock.patch.object(c, "_upload_file_put", side_effect=GpuEncodeError("relay 500")),
mock.patch.object(c, "_upload_mezzanine_to_oss", return_value=("https://oss/signed", "ossk")),
mock.patch.object(
c, "_post_sync",
c,
"_post_sync",
return_value={"job_id": "j", "status": "completed", "ffmpeg_rc": 0, "uploaded": True},
) as m_post,
mock.patch.object(c, "_download_to_file", return_value=50),
@@ -615,6 +612,7 @@ class TestEncodeMezzanineRelay:
with pytest.raises(GpuEncodeError, match="relay PUT failed"):
client._upload_file_put("http://relay/m", f, "video/mp4")
# ── Singleton / factory ────────────────────────────────────────────
class TestSingletonFactory:
def test_build_client_import_error_returns_none(self):