"""Тесты offline install_requirements (OTA).""" from __future__ import annotations import os import tempfile import unittest from pathlib import Path from unittest.mock import patch from install_deps import UpdateDepsError, install_requirements, wheelhouse_has_packages class InstallDepsOfflineTests(unittest.TestCase): def setUp(self) -> None: self._tmp = tempfile.mkdtemp(prefix="wesp-deps-") self.root = Path(self._tmp) (self.root / "requirements-prod.txt").write_text("Flask==2.3.3\n", encoding="utf-8") self.wheels = self.root / "vendor" / "wheels" self.wheels.mkdir(parents=True) (self.wheels / "flask-2.3.3-py3-none-any.whl").write_bytes(b"x") def tearDown(self) -> None: import shutil shutil.rmtree(self._tmp, ignore_errors=True) @patch("install_deps.subprocess.check_call") def test_offline_only_ignores_pypi_allow(self, mock_call) -> None: install_requirements(self.root, offline_only=True) cmd = mock_call.call_args[0][0] self.assertIn("--no-index", cmd) self.assertIn("--ignore-installed", cmd) self.assertTrue(any("--find-links=" in str(a) for a in cmd)) @patch("install_deps.subprocess.check_call") def test_offline_uses_wesp_venv(self, mock_call) -> None: venv = self.root / "prod_venv" bindir = venv / "bin" bindir.mkdir(parents=True) py = bindir / "python3" py.write_text("#!/bin/sh\necho venv\n", encoding="utf-8") py.chmod(0o755) with patch.dict(os.environ, {"WESP_VENV": str(venv)}, clear=False): install_requirements(self.root, offline_only=True) cmd = mock_call.call_args[0][0] self.assertEqual(cmd[0], str(py.resolve())) @patch("install_deps.subprocess.check_call") def test_offline_uses_wes_mac_python_when_present(self, mock_call) -> None: layout = Path(self._tmp) / "layout" app = layout / "wesp" app.mkdir(parents=True) (app / "requirements-prod.txt").write_text("Flask==2.3.3\n", encoding="utf-8") wheels = app / "vendor" / "wheels" wheels.mkdir(parents=True) (wheels / "flask-2.3.3-py3-none-any.whl").write_bytes(b"x") wes_mac = layout / "wes_mac" / "bin" wes_mac.mkdir(parents=True) py = wes_mac / "python3" py.write_text("#!/bin/sh\necho venv\n", encoding="utf-8") py.chmod(0o755) with patch.dict(os.environ, {}, clear=True): install_requirements(app, offline_only=True) cmd = mock_call.call_args[0][0] self.assertEqual(cmd[0], str(py.resolve())) @patch("install_deps.subprocess.check_call") def test_offline_only_with_wheels(self, mock_call) -> None: install_requirements(self.root, offline_only=True) mock_call.assert_called_once() def test_offline_only_empty_wheelhouse_raises(self) -> None: for f in self.wheels.glob("*"): f.unlink() self.assertFalse(wheelhouse_has_packages(self.wheels)) with self.assertRaises(UpdateDepsError): install_requirements(self.root, offline_only=True) @patch.dict(os.environ, {"WESP_OTA_UPDATE": "1"}, clear=False) @patch("install_deps.subprocess.check_call") def test_ota_env_forces_offline(self, mock_call) -> None: install_requirements(self.root, offline_only=False) cmd = mock_call.call_args[0][0] self.assertIn("--no-index", cmd) @patch("install_deps.subprocess.check_call", side_effect=__import__("subprocess").CalledProcessError(1, "pip")) def test_pip_failure_raises_update_deps_error(self, _mock) -> None: with self.assertRaises(UpdateDepsError): install_requirements(self.root, offline_only=True) if __name__ == "__main__": unittest.main()