fix(gpu-encoder): fix unit tests for split relay URLs

- Update tests to use _relay_put_url/_relay_internal_url instead of removed _relay_url
- Fix _fake_response to support chunked read(size) used by _download_to_file
- Fix regex match for error message (rc=1 not ffmpeg_rc=1)
- Add tests for internal/external URL separation and fallback behavior
This commit is contained in:
xiaoxia-agent
2026-09-26 20:17:31 +08:00
committed by saas-backend
parent 30f16c4771
commit 66dc73c8d3
+43 -15
View File
@@ -3,7 +3,6 @@
from __future__ import annotations
import json
import os
import tempfile
import urllib.error
import urllib.request
@@ -34,6 +33,7 @@ def client():
return GpuEncoderClient(
endpoint="http://gpu.example.com:8900",
relay_base_url="http://api.example.com",
relay_internal_base_url="http://api-internal:8000",
sync_timeout=60,
health_timeout=2,
relay_secret="test-secret",
@@ -41,15 +41,20 @@ def client():
def _fake_response(status: int = 200, body: dict | bytes | None = None, headers=None):
"""Fake HTTPResponse that supports chunked read(size) used by _download_to_file."""
if isinstance(body, dict):
data = json.dumps(body).encode("utf-8")
elif body is None:
data = b""
else:
data = body
# Use a real BytesIO so read(size) works for chunked downloads
bio = BytesIO(data)
resp = mock.MagicMock(spec=HTTPResponse)
resp.status = status
resp.read.return_value = data
resp.read.side_effect = lambda n=-1: bio.read(n)
resp.__enter__ = mock.MagicMock(return_value=resp)
resp.__exit__ = mock.MagicMock(return_value=False)
return resp
@@ -111,36 +116,65 @@ class TestPostSync:
)
assert res["status"] == "completed"
assert res["ffmpeg_rc"] == 0
# verify request sent to sync endpoint
req = m.call_args[0][0]
assert req.full_url == "http://gpu.example.com:8900/api/render/sync"
def test_ffmpeg_failure_raises(self, client):
body = {"status": "failed", "ffmpeg_rc": 1, "message": "Invalid data found"}
with mock.patch("urllib.request.urlopen", return_value=_fake_response(body=body)):
with pytest.raises(GpuEncodeError, match="ffmpeg_rc=1"):
with pytest.raises(GpuEncodeError, match="rc=1"):
client._post_sync(
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10}, mezzanine_path=Path("/tmp/x")
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10},
mezzanine_path=Path("/tmp/x"),
)
def test_http_4xx_raises(self, client):
err = urllib.error.HTTPError(
url="http://gpu/render/sync", code=422, msg="Unprocessable", hdrs={}, fp=BytesIO(b"bad request")
url="http://gpu/render/sync",
code=422,
msg="Unprocessable",
hdrs={},
fp=BytesIO(b"bad request"),
)
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}, mezzanine_path=Path("/tmp/x")
{"inputs": {}, "ffmpeg_args": [], "output_url": "", "timeout": 10},
mezzanine_path=Path("/tmp/x"),
)
class TestRelayUrl:
def test_url_contains_token_and_key(self, client):
url = client._relay_url("abc123", "secret!")
def test_put_url_uses_external_base(self, client):
url = client._relay_put_url("abc123", "secret!")
assert "abc123" in url
assert "token=secret%21" in url # urlencoded
assert url.startswith("http://api.example.com/api/v1/internal/gpu-relay/")
def test_internal_url_uses_internal_base(self, client):
url = client._relay_internal_url("abc123", "s")
assert url.startswith("http://api-internal:8000/api/v1/internal/gpu-relay/abc123")
def test_internal_url_falls_back_to_external_when_not_set(self):
c = GpuEncoderClient(
endpoint="http://gpu",
relay_base_url="http://api.example.com",
relay_secret="s",
)
put = c._relay_put_url("k", "s")
internal = c._relay_internal_url("k", "s")
assert put.startswith("http://api.example.com/")
# When internal not set, internal_url falls back to external base
assert internal == put
def test_encode_uses_different_put_and_get_urls(self, client):
"""encode_mezzanine_to_output should use external URL for PUT and internal for GET/DELETE."""
put_url = client._relay_put_url("k", "test-secret")
get_url = client._relay_internal_url("k", "test-secret")
assert "api.example.com" in put_url
assert "api-internal:8000" in get_url
assert put_url != get_url
class TestGetRelaySecret:
def test_explicit_secret_used(self, client):
@@ -175,9 +209,3 @@ class TestDownloadToFile:
with pytest.raises(GpuEncodeError, match="empty file"):
client._download_to_file("http://relay/k", out)
assert not out.exists()
class TestFfmpegOutputToMezzanineIntegration:
"""_ffmpeg_output_to_mezzanine is on UnifiedRenderService; unit-tested there via mocks."""
pass