Skip to content

Commit 544ef27

Browse files
committed
test(training): cover fail-closed HF privacy policy
1 parent 244220b commit 544ef27

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

‎tests/test_hf_dataset_integrity_ledger.py‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ def ledger_paths(tmp_path, monkeypatch):
4444
monkeypatch.setattr(service, "_UPLOADED_DIR", stage / "uploaded")
4545
monkeypatch.setattr(service, "_PENDING_FILE", stage / "pending.jsonl")
4646
stage.mkdir(parents=True, exist_ok=True)
47+
48+
# Keep CI fully offline: model a verified private remote by default.
49+
class PrivateHubInfo:
50+
private = True
51+
52+
class FakeHfApi:
53+
def __init__(self, *args, **kwargs):
54+
pass
55+
56+
def dataset_info(self, *args, **kwargs):
57+
return PrivateHubInfo()
58+
59+
monkeypatch.setattr(service, "HfApi", FakeHfApi, raising=False)
4760
return stage / "training_integrity_ledger.sqlite3"
4861

4962

@@ -519,3 +532,90 @@ def test_queue_cleanup_preserves_unconsented_duplicate_payload(ledger_paths):
519532
remaining = service._read_pending()
520533
assert remaining == [unconsented]
521534
assert remaining[0]["consent"] is False
535+
536+
537+
538+
def test_private_visibility_is_verified_and_allowed(monkeypatch):
539+
class Info:
540+
private = True
541+
542+
class Api:
543+
def __init__(self, *args, **kwargs):
544+
pass
545+
546+
def dataset_info(self, *args, **kwargs):
547+
return Info()
548+
549+
monkeypatch.setattr(service, "HfApi", Api, raising=False)
550+
monkeypatch.setattr(service, "OMNI_HF_DATASET_PRIVATE", True)
551+
assert service._verify_remote_dataset_privacy() is True
552+
553+
554+
def test_public_remote_dataset_is_blocked_when_privacy_is_required(monkeypatch):
555+
class Info:
556+
private = False
557+
558+
class Api:
559+
def __init__(self, *args, **kwargs):
560+
pass
561+
562+
def dataset_info(self, *args, **kwargs):
563+
return Info()
564+
565+
monkeypatch.setattr(service, "HfApi", Api, raising=False)
566+
monkeypatch.setattr(service, "OMNI_HF_DATASET_PRIVATE", True)
567+
monkeypatch.setattr(service, "_dataset_private_env", None)
568+
with pytest.raises(RuntimeError, match="private dataset required but remote dataset is public"):
569+
service._verify_remote_dataset_privacy()
570+
571+
572+
def test_public_visibility_requires_explicit_opt_in_and_metadata_only(monkeypatch):
573+
class Info:
574+
private = False
575+
576+
class Api:
577+
def __init__(self, *args, **kwargs):
578+
pass
579+
580+
def dataset_info(self, *args, **kwargs):
581+
return Info()
582+
583+
monkeypatch.setattr(service, "HfApi", Api, raising=False)
584+
monkeypatch.setattr(service, "_dataset_private_env", "false")
585+
monkeypatch.setattr(service, "OMNI_HF_DATASET_PRIVATE", False)
586+
monkeypatch.setattr(service, "OMNI_HF_EXPORT_RAW_TEXT", False)
587+
assert service._verify_remote_dataset_privacy() is False
588+
589+
monkeypatch.setattr(service, "OMNI_HF_EXPORT_RAW_TEXT", True)
590+
with pytest.raises(RuntimeError, match="incompatible with"):
591+
service._verify_remote_dataset_privacy()
592+
593+
594+
def test_privacy_verification_failure_fails_closed(monkeypatch):
595+
class Api:
596+
def __init__(self, *args, **kwargs):
597+
pass
598+
599+
def dataset_info(self, *args, **kwargs):
600+
raise ConnectionError("visibility endpoint unavailable")
601+
602+
monkeypatch.setattr(service, "HfApi", Api, raising=False)
603+
monkeypatch.setattr(service, "OMNI_HF_DATASET_PRIVATE", True)
604+
with pytest.raises(RuntimeError, match="privacy could not be verified"):
605+
service._verify_remote_dataset_privacy()
606+
607+
608+
def test_unknown_visibility_fails_closed(monkeypatch):
609+
class Info:
610+
private = None
611+
612+
class Api:
613+
def __init__(self, *args, **kwargs):
614+
pass
615+
616+
def dataset_info(self, *args, **kwargs):
617+
return Info()
618+
619+
monkeypatch.setattr(service, "HfApi", Api, raising=False)
620+
with pytest.raises(RuntimeError, match="privacy is unknown"):
621+
service._verify_remote_dataset_privacy()

0 commit comments

Comments
 (0)