Files
mlx-knife/tests_2.0/test_push_dry_run.py
The BROKE Cluster Team 9261bc0c4e 2.0.0-beta.3: Feature Complete - Clone Implementation & Issue Resolution
- Clone Feature (Issue #29): Complete workspace-based workflow with ADR-007
  - Pull Preflight (Issue #30): Prevents cache pollution from gated/private repos
  - Lenient MLX Detection (Issue #31): Framework detection beyond mlx-community
  - Multi-shard Health (Issue #27): Strict completeness validation
  - Full JSON API 0.1.4: Complete schema for all 10 commands
  - Test Suite: 254/254 passed, comprehensive validation

  See CHANGELOG.md fnd TESTING.md or technical implementation details.
2025-09-18 14:09:32 +02:00

122 lines
4.3 KiB
Python

"""Dry-run tests for experimental push (offline, no network).
Covers repo-missing, existing-no-changes, and existing-with-changes cases.
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
import pytest
# Push tests now run by default (alpha features included in standard test suite)
from types import SimpleNamespace
import pytest
from mlxk2.operations.push import push_operation, DEFAULT_PUSH_BRANCH
from mlxk2.output.human import render_push
def _install_fake_hf(monkeypatch, *, repo_exists: bool = True, branch_exists: bool = True, remote_files: list[str] | None = None):
class _Errors:
class HfHubHTTPError(Exception):
pass
class RepositoryNotFoundError(Exception):
pass
class RevisionNotFoundError(Exception):
pass
class _Api:
def __init__(self, token=None):
self.token = token
def repo_info(self, repo_id: str, repo_type: str, revision: str):
if not repo_exists:
raise _Errors.RepositoryNotFoundError("not found")
if not branch_exists:
raise _Errors.RevisionNotFoundError("rev not found")
return {"id": repo_id, "type": repo_type, "rev": revision}
def list_repo_files(self, repo_id: str, repo_type: str, revision: str):
return list(remote_files or [])
# create_repo is only called when create=True (not used in dry-run tests)
def create_repo(self, repo_id: str, repo_type: str, private: bool, exist_ok: bool):
return {"ok": True}
fake = SimpleNamespace(HfApi=_Api, upload_folder=None, errors=_Errors)
# Use monkeypatch to ensure automatic restoration after each test
monkeypatch.setitem(sys.modules, "huggingface_hub", fake)
monkeypatch.setitem(sys.modules, "huggingface_hub.errors", _Errors)
def test_dry_run_repo_missing(tmp_path: Path, monkeypatch):
# Workspace with files; one ignored by default, one via .hfignore
ws = tmp_path / "ws"
ws.mkdir()
(ws / "keep.txt").write_text("x")
(ws / ".DS_Store").write_text("x") # default ignore
(ws / "ignored.log").write_text("x")
(ws / ".hfignore").write_text("ignored.log\n")
monkeypatch.setenv("HF_TOKEN", "dummy")
_install_fake_hf(monkeypatch, repo_exists=False)
res = push_operation(str(ws), "org/model", branch=DEFAULT_PUSH_BRANCH, dry_run=True)
assert res["status"] == "success"
d = res["data"]
assert d.get("dry_run") is True
assert d.get("would_create_repo") is True
assert d.get("would_create_branch") is True
# Only keep.txt should be counted (others ignored)
assert d.get("dry_run_summary", {}).get("added") == 1
# Human line
line = render_push(res)
assert "dry-run:" in line
def test_dry_run_existing_no_changes(tmp_path: Path, monkeypatch):
ws = tmp_path / "ws"
ws.mkdir()
(ws / "a.txt").write_text("1")
(ws / "b.txt").write_text("2")
monkeypatch.setenv("HF_TOKEN", "dummy")
_install_fake_hf(monkeypatch, repo_exists=True, branch_exists=True, remote_files=["a.txt", "b.txt"])
res = push_operation(str(ws), "org/model", branch=DEFAULT_PUSH_BRANCH, dry_run=True)
assert res["status"] == "success"
d = res["data"]
assert d.get("dry_run") is True
assert d.get("no_changes") is True
assert d.get("dry_run_summary", {}).get("added") == 0
assert d.get("dry_run_summary", {}).get("deleted") == 0
assert d.get("message") == "Dry-run: no changes"
def test_dry_run_existing_with_changes(tmp_path: Path, monkeypatch):
ws = tmp_path / "ws"
ws.mkdir()
# Local: a.txt (shared), new.txt (to add)
(ws / "a.txt").write_text("1")
(ws / "new.txt").write_text("x")
monkeypatch.setenv("HF_TOKEN", "dummy")
# Remote: a.txt (shared), gone.txt (to delete)
_install_fake_hf(monkeypatch, repo_exists=True, branch_exists=True, remote_files=["a.txt", "gone.txt"])
res = push_operation(str(ws), "org/model", branch=DEFAULT_PUSH_BRANCH, dry_run=True)
assert res["status"] == "success"
d = res["data"]
assert d.get("dry_run") is True
assert d.get("no_changes") is False
assert d.get("dry_run_summary", {}).get("added") == 1
assert d.get("dry_run_summary", {}).get("deleted") == 1
assert d.get("message") == "Dry-run: +1 ~? -1"
# Human line should reflect plan
line = render_push(res)
assert "dry-run: +1 ~? -1" in line