|
| 1 | +"""Interrupted downloads. Does not require running AYON server.""" |
| 2 | +import io |
| 3 | + |
| 4 | +import pytest |
| 5 | + |
| 6 | +from ayon_api.server_api import ServerAPI |
| 7 | +from ayon_api.utils import RequestTypes |
| 8 | + |
| 9 | +from .fake_transfer import FakeResponse |
| 10 | + |
| 11 | +CONTENT = b"0123456789" |
| 12 | +SIZE_HEADER = {"Content-Length": str(len(CONTENT))} |
| 13 | + |
| 14 | + |
| 15 | +@pytest.fixture |
| 16 | +def con(monkeypatch): |
| 17 | + monkeypatch.setattr("time.sleep", lambda *args, **kwargs: None) |
| 18 | + return ServerAPI("http://localhost:0", create_session=False, max_retries=3) |
| 19 | + |
| 20 | + |
| 21 | +def _download(con, get_func): |
| 22 | + con._base_functions_mapping[RequestTypes.get] = get_func |
| 23 | + stream = io.BytesIO() |
| 24 | + progress = con.download_file_to_stream("api/file", stream) |
| 25 | + return stream.getvalue(), progress |
| 26 | + |
| 27 | + |
| 28 | +def test_incomplete_download_is_continued(con): |
| 29 | + def get_func(url, **kwargs): |
| 30 | + if "Range" not in kwargs["headers"]: |
| 31 | + # Connection closed after 4 bytes without an exception |
| 32 | + return FakeResponse(200, CONTENT[:4], SIZE_HEADER) |
| 33 | + assert kwargs["headers"]["Range"] == "bytes=4-" |
| 34 | + return FakeResponse(206, CONTENT[4:], {"Content-Length": "6"}) |
| 35 | + |
| 36 | + content, progress = _download(con, get_func) |
| 37 | + assert content == CONTENT |
| 38 | + assert progress.transferred_size == len(CONTENT) |
| 39 | + |
| 40 | + |
| 41 | +def test_resume_without_range_support_does_not_duplicate(con): |
| 42 | + calls = [] |
| 43 | + |
| 44 | + def get_func(url, **kwargs): |
| 45 | + calls.append(url) |
| 46 | + if len(calls) == 1: |
| 47 | + return FakeResponse(200, CONTENT[:4], SIZE_HEADER) |
| 48 | + # Server ignores 'Range' header and sends whole file again |
| 49 | + return FakeResponse(200, CONTENT, SIZE_HEADER) |
| 50 | + |
| 51 | + content, progress = _download(con, get_func) |
| 52 | + assert content == CONTENT |
| 53 | + assert progress.transferred_size == len(CONTENT) |
| 54 | + |
| 55 | + |
| 56 | +def test_download_without_content_length(con): |
| 57 | + content, _ = _download( |
| 58 | + con, lambda url, **kwargs: FakeResponse(200, CONTENT) |
| 59 | + ) |
| 60 | + assert content == CONTENT |
0 commit comments