Files
wehub-resource-sync 16031aae96
CPU tests Workflow / Testing (ubuntu-latest, 3.12) (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.13) (push) Failing after 0s
Mypy Type Check / Type Check (push) Failing after 0s
Docs/Test WorkFlow / Test docs build (push) Failing after 1s
PR Conflict Labeler / labeling (push) Failing after 1s
Dependency resolution / Resolve [tflite] extra — Python 3.12 (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.10) (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.13) (push) Failing after 1s
CPU tests Workflow / build-pkg (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.10) (push) Failing after 0s
CPU tests Workflow / Testing (ubuntu-latest, 3.11) (push) Failing after 0s
Smoke Tests / try-all-models (macos-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (macos-latest, 3.13) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / testing-guardian (push) Has been cancelled
GPU tests Workflow / Testing (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:26:24 +08:00

119 lines
4.5 KiB
Python

# ------------------------------------------------------------------------
# RF-DETR
# Copyright (c) 2025 Roboflow. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
# ------------------------------------------------------------------------
"""Tests for private developer download helpers."""
import io
import zipfile
from pathlib import Path
from unittest.mock import patch
import pytest
from rfdetr.datasets._develop import (
_coco_val_images_complete,
_download_and_extract,
_download_lock,
_nonempty_file_exists,
)
class TestCocoValImagesComplete:
"""Regression coverage for interrupted COCO val2017 image downloads."""
def test_missing_directory_is_incomplete(self, tmp_path: Path) -> None:
"""A missing image directory must trigger a download."""
assert not _coco_val_images_complete(tmp_path / "val2017")
def test_empty_existing_directory_is_incomplete(self, tmp_path: Path) -> None:
"""An empty ``val2017`` directory must not skip the image download."""
images_root = tmp_path / "val2017"
images_root.mkdir()
assert not _coco_val_images_complete(images_root)
@pytest.mark.parametrize(
"file_count,expected",
[
pytest.param(1, False, id="below_threshold_is_incomplete"),
pytest.param(2, True, id="at_threshold_is_complete"),
pytest.param(3, True, id="above_threshold_is_complete"),
],
)
def test_file_count_threshold(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch, file_count: int, expected: bool
) -> None:
"""Directory completeness reflects the >= threshold semantics."""
import rfdetr.datasets._develop as _develop_mod
monkeypatch.setattr(_develop_mod, "_COCO_VAL_IMAGE_COUNT", 2)
images_root = tmp_path / "val2017"
images_root.mkdir()
for i in range(file_count):
(images_root / f"{i:012d}.jpg").write_bytes(b"jpeg")
assert _coco_val_images_complete(images_root) is expected
class TestNonemptyFileExists:
"""Regression coverage for annotation file integrity checks in benchmark downloads."""
def test_missing_file_is_incomplete(self, tmp_path: Path) -> None:
"""A missing annotation file must trigger a download."""
annotations_path = tmp_path / "instances_val2017.json"
assert not _nonempty_file_exists(annotations_path)
def test_empty_file_is_incomplete(self, tmp_path: Path) -> None:
"""An empty annotation file must trigger a re-download."""
annotations_path = tmp_path / "instances_val2017.json"
annotations_path.write_bytes(b"")
assert not _nonempty_file_exists(annotations_path)
def test_nonempty_file_is_complete(self, tmp_path: Path) -> None:
"""A non-empty annotation file is accepted without re-download."""
annotations_path = tmp_path / "instances_val2017.json"
annotations_path.write_bytes(b"{}")
assert _nonempty_file_exists(annotations_path)
class TestDownloadLock:
"""Coverage for the cross-process file-lock context manager."""
def test_timeout_raises_when_lock_held(self, tmp_path: Path) -> None:
"""TimeoutError is raised immediately when the lock file already exists and timeout_s=0."""
lock_path = tmp_path / "test.lock"
lock_path.touch()
with pytest.raises(TimeoutError):
with _download_lock(lock_path, timeout_s=0, poll_s=0):
pass
class TestDownloadAndExtract:
"""Coverage for the ZIP download-and-extract helper."""
def _make_zip(self, members: dict) -> bytes:
"""Build an in-memory ZIP archive from a mapping of filename→content."""
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
for name, content in members.items():
zf.writestr(name, content)
return buf.getvalue()
def test_path_traversal_raises_runtime_error(self, tmp_path: Path) -> None:
"""A ZIP entry escaping dest_dir must raise RuntimeError (path-traversal guard)."""
zip_bytes = self._make_zip({"../evil.txt": "malicious"})
url = "http://example.com/test.zip"
def fake_urlretrieve(url: str, dest: str) -> None:
Path(dest).write_bytes(zip_bytes)
with patch("rfdetr.datasets._develop.urlretrieve", side_effect=fake_urlretrieve):
with pytest.raises(RuntimeError, match="Unsafe path detected"):
_download_and_extract(url, tmp_path)