@@ -155,6 +155,22 @@ class TestInstallOnePythonExecutable:
155155 def git (self ):
156156 return GitRepo (url = "./git_url" , commit = "commit_hash" )
157157
158+ @pytest .fixture
159+ def setup_repo (self , installer : SlurmInstaller , git : GitRepo ):
160+ repo_dir = installer .system .install_path / git .repo_name
161+ subdir = repo_dir / "subdir"
162+
163+ repo_dir .mkdir (parents = True , exist_ok = True )
164+ subdir .mkdir (parents = True , exist_ok = True )
165+
166+ pyproject_file = subdir / "pyproject.toml"
167+ requirements_file = subdir / "requirements.txt"
168+
169+ pyproject_file .touch ()
170+ requirements_file .touch ()
171+
172+ return repo_dir , subdir , pyproject_file , requirements_file
173+
158174 def test_venv_created (self , installer : SlurmInstaller , git : GitRepo ):
159175 py = PythonExecutable (git )
160176 venv_path = installer .system .install_path / py .venv_name
@@ -184,10 +200,14 @@ def test_venv_already_exists(self, installer: SlurmInstaller, git: GitRepo):
184200 assert res .success
185201 assert res .message == f"Virtual environment already exists at { venv_path } ."
186202
187- def test_requiretements_no_file (self , installer : SlurmInstaller ):
188- res = installer ._install_requirements (
189- installer .system .install_path , installer .system .install_path / "requirements.txt"
190- )
203+ def test_requirements_no_file (self , installer : SlurmInstaller , git : GitRepo ):
204+ py = PythonExecutable (git )
205+ venv_path = installer .system .install_path / py .venv_name
206+ with patch ("subprocess.run" ) as mock_run :
207+ mock_run .return_value = CompletedProcess (args = [], returncode = 0 )
208+ res = installer ._create_venv (venv_path )
209+ assert res .success
210+ res = installer ._install_requirements (venv_path , installer .system .install_path / "requirements.txt" )
191211 assert not res .success
192212 assert (
193213 res .message
@@ -196,20 +216,14 @@ def test_requiretements_no_file(self, installer: SlurmInstaller):
196216
197217 def test_requirements_installed (self , installer : SlurmInstaller ):
198218 requirements_file = installer .system .install_path / "requirements.txt"
219+ venv_path = installer .system .install_path / "venv"
199220 requirements_file .touch ()
200221 with patch ("subprocess.run" ) as mock_run :
201222 mock_run .return_value = CompletedProcess (args = [], returncode = 0 )
202- res = installer ._install_requirements (installer . system . install_path , requirements_file )
223+ res = installer ._install_requirements (venv_path , requirements_file )
203224 assert res .success
204225 mock_run .assert_called_once_with (
205- [
206- installer .system .install_path / "bin" / "python" ,
207- "-m" ,
208- "pip" ,
209- "install" ,
210- "-r" ,
211- str (requirements_file ),
212- ],
226+ [str (venv_path / "bin" / "python" ), "-m" , "pip" , "install" , "-r" , str (requirements_file )],
213227 capture_output = True ,
214228 text = True ,
215229 )
@@ -221,15 +235,22 @@ def test_requirements_not_installed(self, installer: SlurmInstaller):
221235 mock_run .return_value = CompletedProcess (args = [], returncode = 1 , stderr = "err" )
222236 res = installer ._install_requirements (installer .system .install_path , requirements_file )
223237 assert not res .success
224- assert res .message == "Failed to install requirements: err"
238+ assert res .message == "Failed to install dependencies from requirements.txt : err"
225239
226240 def test_all_good_flow (self , installer : SlurmInstaller , git : GitRepo ):
227241 py = PythonExecutable (git )
228242 py .git_repo .installed_path = installer .system .install_path / py .git_repo .repo_name
243+
244+ repo_dir = py .git_repo .installed_path
245+ repo_dir .mkdir (parents = True , exist_ok = True )
246+ pyproject_file = repo_dir / "pyproject.toml"
247+ pyproject_file .write_text ("[tool.poetry]\n name = 'dummy_project'" )
248+
229249 installer ._install_one_git_repo = Mock (return_value = InstallStatusResult (True ))
230250 installer ._clone_repository = Mock (return_value = InstallStatusResult (True ))
231251 installer ._checkout_commit = Mock (return_value = InstallStatusResult (True ))
232252 installer ._create_venv = Mock (return_value = InstallStatusResult (True ))
253+ installer ._install_pyproject = Mock (return_value = InstallStatusResult (True ))
233254 installer ._install_requirements = Mock (return_value = InstallStatusResult (True ))
234255 res = installer ._install_python_executable (py )
235256 assert res .success
@@ -286,6 +307,50 @@ def test_uninstall_venv_removed_ok(self, installer: SlurmInstaller, git: GitRepo
286307 assert not (installer .system .install_path / py .venv_name ).exists ()
287308 assert not py .venv_path
288309
310+ def test_install_python_executable_prefers_pyproject_toml (
311+ self , installer : SlurmInstaller , git : GitRepo , setup_repo
312+ ):
313+ repo_dir , subdir , _ , _ = setup_repo
314+
315+ py = PythonExecutable (git , project_subpath = Path ("subdir" ), dependencies_from_pyproject = True )
316+
317+ installer ._install_one_git_repo = Mock (return_value = InstallStatusResult (True ))
318+ installer ._create_venv = Mock (return_value = InstallStatusResult (True ))
319+ installer ._install_requirements = Mock (return_value = InstallStatusResult (True ))
320+ installer ._install_pyproject = Mock (return_value = InstallStatusResult (True ))
321+
322+ py .git_repo .installed_path = repo_dir
323+
324+ res = installer ._install_python_executable (py )
325+
326+ assert res .success
327+ installer ._install_pyproject .assert_called_once_with (installer .system .install_path / py .venv_name , subdir )
328+ installer ._install_requirements .assert_not_called ()
329+ assert py .venv_path == installer .system .install_path / py .venv_name
330+
331+ def test_install_python_executable_prefers_requirements_txt (
332+ self , installer : SlurmInstaller , git : GitRepo , setup_repo
333+ ):
334+ repo_dir , subdir , _ , requirements_file = setup_repo
335+
336+ py = PythonExecutable (git , project_subpath = Path ("subdir" ), dependencies_from_pyproject = False )
337+
338+ installer ._install_one_git_repo = Mock (return_value = InstallStatusResult (True ))
339+ installer ._create_venv = Mock (return_value = InstallStatusResult (True ))
340+ installer ._install_requirements = Mock (return_value = InstallStatusResult (True ))
341+ installer ._install_pyproject = Mock (return_value = InstallStatusResult (True ))
342+
343+ py .git_repo .installed_path = repo_dir
344+
345+ res = installer ._install_python_executable (py )
346+
347+ assert res .success
348+ installer ._install_requirements .assert_called_once_with (
349+ installer .system .install_path / py .venv_name , requirements_file
350+ )
351+ installer ._install_pyproject .assert_not_called ()
352+ assert py .venv_path == installer .system .install_path / py .venv_name
353+
289354
290355class TestGitRepo :
291356 @pytest .fixture
0 commit comments