|
6 | 6 | from collections.abc import Callable, Iterator |
7 | 7 | from pathlib import Path |
8 | 8 | from tempfile import TemporaryDirectory |
| 9 | +from types import SimpleNamespace |
9 | 10 | from typing import TYPE_CHECKING, Any, NoReturn |
10 | 11 | from unittest.mock import AsyncMock, patch |
11 | 12 |
|
|
14 | 15 | from pytest_httpx import HTTPXMock |
15 | 16 |
|
16 | 17 | from cognite.client import CogniteClient |
| 18 | +from cognite.client._api.files import FilesAPI |
17 | 19 | from cognite.client._constants import FILE_MAX_MULTIPART_COUNT, FILE_MAX_MULTIPART_SIZE, FILE_MIN_MULTIPART_SIZE |
18 | 20 | from cognite.client.config import global_config |
19 | 21 | from cognite.client.data_classes import GeoLocation, GeoLocationFilter, Geometry, GeometryFilter, TimestampRange |
@@ -1185,6 +1187,46 @@ def test_upload_semaphore_limits_concurrent_parts( |
1185 | 1187 | assert peak == concurrency_limit |
1186 | 1188 |
|
1187 | 1189 |
|
| 1190 | +@pytest.fixture |
| 1191 | +def lying_stat(monkeypatch: pytest.MonkeyPatch) -> None: |
| 1192 | + """Monkeypatch Path.stat to report st_size=0, mimicking Pyodide's broken fstat.""" |
| 1193 | + monkeypatch.setattr(Path, "stat", lambda _path, **_kw: SimpleNamespace(st_size=0)) |
| 1194 | + |
| 1195 | + |
| 1196 | +class TestGetFileSize: |
| 1197 | + def test_browser_falls_back_to_seek_when_stat_lies( |
| 1198 | + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch, lying_stat: None |
| 1199 | + ) -> None: |
| 1200 | + """Pyodide /drive/... regression: stat reports 0 but the file -has- bytes.""" |
| 1201 | + p = tmp_path / "lied_about.bin" |
| 1202 | + p.write_bytes(b"hey\nyo\n") # 7 bytes really on disk |
| 1203 | + # We have to pretend we are running in the browser with Pyodide: |
| 1204 | + monkeypatch.setattr("cognite.client._api.files._RUNNING_IN_BROWSER", True) |
| 1205 | + |
| 1206 | + # Sanity-check that stat is now lying: |
| 1207 | + assert p.stat().st_size == 0 |
| 1208 | + # The helper should still report correct size: |
| 1209 | + assert FilesAPI._get_file_size(p) == 7 |
| 1210 | + |
| 1211 | + def test_empty_file_in_browser_still_reports_zero(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: |
| 1212 | + """A genuinely empty file must still report size=0 in browser mode.""" |
| 1213 | + p = tmp_path / "empty.bin" |
| 1214 | + p.touch() |
| 1215 | + monkeypatch.setattr("cognite.client._api.files._RUNNING_IN_BROWSER", True) |
| 1216 | + |
| 1217 | + assert FilesAPI._get_file_size(p) == 0 |
| 1218 | + |
| 1219 | + def test_returns_stat_size_for_non_empty_file(self, tmp_path: Path) -> None: |
| 1220 | + p = tmp_path / "x.bin" |
| 1221 | + p.write_bytes(b"hello world") |
| 1222 | + assert FilesAPI._get_file_size(p) == 11 |
| 1223 | + |
| 1224 | + def test_returns_zero_for_genuinely_empty_file(self, tmp_path: Path) -> None: |
| 1225 | + p = tmp_path / "empty.bin" |
| 1226 | + p.touch() |
| 1227 | + assert FilesAPI._get_file_size(p) == 0 |
| 1228 | + |
| 1229 | + |
1188 | 1230 | @pytest.fixture |
1189 | 1231 | def mock_files_empty( |
1190 | 1232 | httpx_mock: HTTPXMock, cognite_client: CogniteClient, async_client: AsyncCogniteClient |
|
0 commit comments