| |
| |
| |
| |
| |
|
|
| """Tests for the openenv push command.""" |
|
|
| import os |
| from pathlib import Path |
| from unittest.mock import MagicMock, patch |
|
|
| from openenv.cli.__main__ import app |
| from typer.testing import CliRunner |
|
|
|
|
| runner = CliRunner() |
|
|
|
|
| def _create_test_openenv_env(env_dir: Path, env_name: str = "test_env") -> None: |
| """Create a complete OpenEnv environment for testing.""" |
| import yaml |
|
|
| |
| manifest = { |
| "spec_version": 1, |
| "name": env_name, |
| "type": "space", |
| "runtime": "fastapi", |
| "app": "server.app:app", |
| "port": 8000, |
| } |
| with open(env_dir / "openenv.yaml", "w") as f: |
| yaml.dump(manifest, f) |
|
|
| |
| pyproject_content = f"""[project] |
| name = "{env_name}" |
| version = "0.1.0" |
| dependencies = ["openenv[core]>=0.2.0"] |
| """ |
| (env_dir / "pyproject.toml").write_text(pyproject_content) |
|
|
| |
| (env_dir / "__init__.py").write_text("# Test environment\n") |
|
|
| |
| (env_dir / "client.py").write_text("# Test client\n") |
|
|
| |
| (env_dir / "models.py").write_text("# Test models\n") |
|
|
| |
| (env_dir / "server").mkdir(exist_ok=True) |
| (env_dir / "server" / "__init__.py").write_text("# Server module\n") |
| (env_dir / "server" / "app.py").write_text("# App module\n") |
| (env_dir / "server" / "Dockerfile").write_text( |
| 'FROM openenv-base:latest\nCMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "8000"]\n' |
| ) |
|
|
| |
| readme_content = """--- |
| title: Test Environment |
| sdk: docker |
| app_port: 8000 |
| --- |
| |
| # Test Environment |
| """ |
| (env_dir / "README.md").write_text(readme_content) |
|
|
|
|
| def test_push_validates_openenv_directory(tmp_path: Path) -> None: |
| """Test that push validates openenv.yaml is present.""" |
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert ( |
| "openenv.yaml" in result.output.lower() or "manifest" in result.output.lower() |
| ) |
|
|
|
|
| def test_push_validates_openenv_yaml_format(tmp_path: Path) -> None: |
| """Test that push validates openenv.yaml format.""" |
| |
| _create_test_openenv_env(tmp_path) |
| (tmp_path / "openenv.yaml").write_text("invalid: yaml: content: [") |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "parse" in result.output.lower() or "yaml" in result.output.lower() |
|
|
|
|
| def test_push_validates_openenv_yaml_has_name(tmp_path: Path) -> None: |
| """Test that push validates openenv.yaml has a name field.""" |
| import yaml |
|
|
| |
| _create_test_openenv_env(tmp_path) |
| manifest = {"spec_version": 1, "type": "space"} |
| with open(tmp_path / "openenv.yaml", "w") as f: |
| yaml.dump(manifest, f) |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "name" in result.output.lower() |
|
|
|
|
| def test_push_authenticates_with_hf(tmp_path: Path) -> None: |
| """Test that push ensures Hugging Face authentication.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
|
|
| |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_whoami.called |
|
|
|
|
| def test_push_enables_web_interface_in_dockerfile(tmp_path: Path) -> None: |
| """Test that push enables web interface in Dockerfile.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_updates_readme_frontmatter(tmp_path: Path) -> None: |
| """Test that push updates README frontmatter with base_path.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| |
| readme_content = """--- |
| title: Test Environment |
| sdk: docker |
| app_port: 8000 |
| --- |
| |
| # Test Environment |
| """ |
| (tmp_path / "README.md").write_text(readme_content) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_uses_repo_id_option(tmp_path: Path) -> None: |
| """Test that push respects --repo-id option.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push", "--repo-id", "custom-org/my-env"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| mock_api.create_repo.assert_called_once() |
| call_args = mock_api.create_repo.call_args |
| assert call_args.kwargs["repo_id"] == "custom-org/my-env" |
|
|
|
|
| def test_push_uses_default_repo_id(tmp_path: Path) -> None: |
| """Test that push uses default repo-id from username and env name.""" |
| _create_test_openenv_env(tmp_path, env_name="test_env") |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| mock_api.create_repo.assert_called_once() |
| call_args = mock_api.create_repo.call_args |
| assert call_args.kwargs["repo_id"] == "testuser/test_env" |
|
|
|
|
| def test_push_uses_private_option(tmp_path: Path) -> None: |
| """Test that push respects --private option.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push", "--private"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| mock_api.create_repo.assert_called_once() |
| call_args = mock_api.create_repo.call_args |
| assert call_args.kwargs["private"] is True |
|
|
|
|
| def test_push_uses_base_image_option(tmp_path: Path) -> None: |
| """Test that push respects --base-image option.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push", "--base-image", "custom-base:latest"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_uses_directory_argument(tmp_path: Path) -> None: |
| """Test that push respects directory argument.""" |
| env_dir = tmp_path / "my_env" |
| env_dir.mkdir() |
| _create_test_openenv_env(env_dir) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| |
| result = runner.invoke( |
| app, |
| ["push", str(env_dir)], |
| ) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_accepts_dockerfile_at_env_root(tmp_path: Path) -> None: |
| """Test that push works when Dockerfile is at environment root instead of server/.""" |
| _create_test_openenv_env(tmp_path) |
| |
| root_dockerfile = tmp_path / "Dockerfile" |
| (tmp_path / "server" / "Dockerfile").rename(root_dockerfile) |
|
|
| staged_files: list[list[str]] = [] |
|
|
| def _capture_staging(*, folder_path: str, **_: object) -> None: |
| staging = Path(folder_path) |
| staged_files.append( |
| sorted( |
| str(p.relative_to(staging)) for p in staging.rglob("*") if p.is_file() |
| ) |
| ) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_api.upload_folder.side_effect = _capture_staging |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code == 0, result.output |
| assert mock_api.upload_folder.called |
|
|
| |
| files = staged_files[0] |
| assert "Dockerfile" in files |
| assert "server/Dockerfile" not in files |
|
|
|
|
| def test_push_handles_missing_dockerfile(tmp_path: Path) -> None: |
| """Test that push fails when Dockerfile is missing (required for deployment).""" |
| _create_test_openenv_env(tmp_path) |
| |
| (tmp_path / "server" / "Dockerfile").unlink() |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert result.exit_code != 0 |
| assert "dockerfile" in result.output.lower() or "missing" in result.output.lower() |
|
|
|
|
| def test_push_handles_missing_readme(tmp_path: Path) -> None: |
| """Test that push fails when README.md is missing (required for deployment).""" |
| _create_test_openenv_env(tmp_path) |
| |
| (tmp_path / "README.md").unlink() |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert result.exit_code != 0 |
| assert "readme" in result.output.lower() or "missing" in result.output.lower() |
|
|
|
|
| def test_push_initializes_hf_api_without_token(tmp_path: Path) -> None: |
| """Test that push initializes HfApi without token parameter.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| mock_hf_api_class.assert_called_once() |
| call_args = mock_hf_api_class.call_args |
| |
| assert "token" not in (call_args.kwargs or {}) |
|
|
|
|
| def test_push_validates_repo_id_format(tmp_path: Path) -> None: |
| """Test that push validates repo-id format.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| |
| result = runner.invoke(app, ["push", "--repo-id", "invalid-repo-id"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "repo-id" in result.output.lower() or "format" in result.output.lower() |
|
|
|
|
| def test_push_validates_manifest_is_dict(tmp_path: Path) -> None: |
| """Test that push validates manifest is a dictionary.""" |
| import yaml |
|
|
| |
| _create_test_openenv_env(tmp_path) |
| with open(tmp_path / "openenv.yaml", "w") as f: |
| yaml.dump("not a dict", f) |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "dictionary" in result.output.lower() or "yaml" in result.output.lower() |
|
|
|
|
| def test_push_handles_whoami_object_return(tmp_path: Path) -> None: |
| """Test that push handles whoami returning an object instead of dict.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| |
| class MockUser: |
| def __init__(self): |
| self.name = "testuser" |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = MockUser() |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_handles_authentication_failure(tmp_path: Path) -> None: |
| """Test that push handles authentication failure.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| |
| |
| mock_whoami.side_effect = Exception("Not authenticated") |
| mock_login.side_effect = Exception("Login failed") |
| |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert ( |
| "authentication" in result.output.lower() |
| or "login" in result.output.lower() |
| ) |
|
|
|
|
| def test_push_handles_whoami_missing_username(tmp_path: Path) -> None: |
| """Test that push handles whoami response without username.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| |
| mock_whoami.return_value = {} |
| |
| mock_login.return_value = None |
| |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "username" in result.output.lower() or "extract" in result.output.lower() |
|
|
|
|
| def test_push_handles_readme_without_frontmatter(tmp_path: Path) -> None: |
| """Test that push handles README without frontmatter.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| |
| (tmp_path / "README.md").write_text("# Test Environment\nNo frontmatter here.\n") |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_handles_hf_api_create_repo_error(tmp_path: Path) -> None: |
| """Test that push handles HF API create_repo error.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_api.create_repo.side_effect = Exception("API Error") |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_handles_hf_api_upload_error(tmp_path: Path) -> None: |
| """Test that push handles HF API upload_folder error.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_api.upload_folder.side_effect = Exception("Upload failed") |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "upload" in result.output.lower() or "failed" in result.output.lower() |
|
|
|
|
| def test_push_handles_base_image_not_found_in_dockerfile(tmp_path: Path) -> None: |
| """Test that push handles Dockerfile without FROM line.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| |
| (tmp_path / "server" / "Dockerfile").write_text( |
| 'RUN echo \'test\'\nCMD ["echo", "test"]\n' |
| ) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push", "--base-image", "custom-base:latest"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_excludes_files_from_ignore_file(tmp_path: Path) -> None: |
| """Test that push excludes files using patterns loaded via --exclude.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| |
| (tmp_path / "excluded_dir").mkdir() |
| (tmp_path / "excluded_dir" / "secret.txt").write_text("do not upload") |
| (tmp_path / "weights.bin").write_text("binary payload") |
| (tmp_path / "keep.txt").write_text("keep me") |
|
|
| ignore_file = tmp_path / ".openenvignore" |
| ignore_file.write_text( |
| """ |
| # comments and empty lines are ignored |
| excluded_dir/ |
| *.bin |
| """ |
| ) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| def _assert_upload_payload(*_unused_args, **kwargs): |
| ignore_patterns = kwargs["ignore_patterns"] |
| assert "excluded_dir/" in ignore_patterns |
| assert "*.bin" in ignore_patterns |
| assert ".*" in ignore_patterns |
|
|
| staged = Path(kwargs["folder_path"]) |
| assert not (staged / "excluded_dir").exists() |
| assert not (staged / "weights.bin").exists() |
| assert (staged / "keep.txt").exists() |
|
|
| mock_api.upload_folder.side_effect = _assert_upload_payload |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke( |
| app, |
| ["push", "--exclude", ".openenvignore"], |
| ) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code == 0 |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_does_not_use_gitignore_as_default_excludes(tmp_path: Path) -> None: |
| """Test that .gitignore patterns are not used by default.""" |
| _create_test_openenv_env(tmp_path) |
| (tmp_path / ".gitignore").write_text("excluded_from_gitignore/\n") |
| (tmp_path / "excluded_from_gitignore").mkdir() |
| (tmp_path / "excluded_from_gitignore" / "secret.txt").write_text("upload me") |
| (tmp_path / "keep.txt").write_text("keep me") |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| def _assert_upload_payload(*_unused_args, **kwargs): |
| ignore_patterns = kwargs["ignore_patterns"] |
| assert "excluded_from_gitignore/" not in ignore_patterns |
|
|
| staged = Path(kwargs["folder_path"]) |
| assert (staged / "excluded_from_gitignore").exists() |
| assert (staged / "keep.txt").exists() |
|
|
| mock_api.upload_folder.side_effect = _assert_upload_payload |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke(app, ["push"]) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code == 0 |
| assert mock_api.upload_folder.called |
|
|
|
|
| def test_push_fails_when_exclude_file_missing(tmp_path: Path) -> None: |
| """Test that push fails if --exclude points to a missing file.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke( |
| app, |
| ["push", "--exclude", "missing.ignore"], |
| ) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code != 0 |
| assert "exclude file" in result.output.lower() |
|
|
|
|
| def test_push_create_pr_sets_upload_flag_and_skips_create_repo(tmp_path: Path) -> None: |
| """Test that --create-pr uploads with PR mode and skips repo creation.""" |
| _create_test_openenv_env(tmp_path) |
|
|
| with ( |
| patch("openenv.cli.commands.push.whoami") as mock_whoami, |
| patch("openenv.cli.commands.push.login") as mock_login, |
| patch("openenv.cli.commands.push.HfApi") as mock_hf_api_class, |
| ): |
| mock_whoami.return_value = {"name": "testuser"} |
| mock_login.return_value = None |
| mock_api = MagicMock() |
| mock_hf_api_class.return_value = mock_api |
|
|
| old_cwd = os.getcwd() |
| try: |
| os.chdir(str(tmp_path)) |
| result = runner.invoke( |
| app, ["push", "--repo-id", "my-org/my-env", "--create-pr"] |
| ) |
| finally: |
| os.chdir(old_cwd) |
|
|
| assert result.exit_code == 0 |
| mock_api.upload_folder.assert_called_once() |
| call_kwargs = mock_api.upload_folder.call_args[1] |
| assert call_kwargs.get("create_pr") is True |
| |
| mock_api.create_repo.assert_not_called() |
|
|