1+ from typing import Optional
12from unittest .mock import patch
23
34import pytest
45
56from dstack ._internal .core .models .configurations import TaskConfiguration
67from dstack ._internal .core .models .runs import JobSSHKey
8+ from dstack ._internal .server .services .docker import ImageConfig
79from dstack ._internal .server .services .jobs .configurators .task import TaskJobConfigurator
810from dstack ._internal .server .testing .common import get_run_spec
911
1012
1113@pytest .mark .asyncio
1214@pytest .mark .usefixtures ("image_config_mock" )
13- class TestTaskJobConfigurator :
14- async def test_ssh_key_single_node (self ):
15+ class TestSSHKey :
16+ async def test_single_node (self ):
1517 configuration = TaskConfiguration (nodes = 1 , image = "debian" )
1618 run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
1719 configurator = TaskJobConfigurator (run_spec )
@@ -21,7 +23,7 @@ async def test_ssh_key_single_node(self):
2123 assert len (job_specs ) == 1
2224 assert job_specs [0 ].ssh_key is None
2325
24- async def test_ssh_key_multi_node (self ):
26+ async def test_multi_node (self ):
2527 configuration = TaskConfiguration (nodes = 2 , image = "debian" )
2628 run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
2729 configurator = TaskJobConfigurator (run_spec )
@@ -33,3 +35,74 @@ async def test_ssh_key_multi_node(self):
3335 assert len (job_specs ) == 2
3436 assert job_specs [0 ].ssh_key == JobSSHKey (private = "private1" , public = "public1" )
3537 assert job_specs [1 ].ssh_key == JobSSHKey (private = "private1" , public = "public1" )
38+
39+
40+ @pytest .mark .asyncio
41+ @pytest .mark .usefixtures ("image_config_mock" )
42+ class TestCommands :
43+ @pytest .mark .parametrize (
44+ ["commands" , "expected_commands" ],
45+ [
46+ pytest .param ([], ["/entrypoint.sh" , "-v" ], id = "no-commands" ),
47+ pytest .param (["-x" , "-u" ], ["/entrypoint.sh" , "-v" , "-x" , "-u" ], id = "with-commands" ),
48+ ],
49+ )
50+ async def test_with_entrypoint (self , commands : list [str ], expected_commands : list [str ]):
51+ configuration = TaskConfiguration (
52+ image = "debian" ,
53+ entrypoint = "/entrypoint.sh -v" ,
54+ commands = commands ,
55+ )
56+ run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
57+ configurator = TaskJobConfigurator (run_spec )
58+
59+ job_specs = await configurator .get_job_specs (replica_num = 0 )
60+
61+ assert job_specs [0 ].commands == expected_commands
62+
63+ @pytest .mark .parametrize (
64+ ["shell" , "expected_shell" ],
65+ [
66+ pytest .param (None , "/bin/sh" , id = "default-shell" ),
67+ pytest .param ("sh" , "/bin/sh" , id = "sh" ),
68+ pytest .param ("bash" , "/bin/bash" , id = "bash" ),
69+ pytest .param ("/usr/bin/zsh" , "/usr/bin/zsh" , id = "custom-shell" ),
70+ ],
71+ )
72+ async def test_with_commands_and_image (self , shell : Optional [str ], expected_shell : str ):
73+ configuration = TaskConfiguration (image = "debian" , commands = ["sleep inf" ], shell = shell )
74+ run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
75+ configurator = TaskJobConfigurator (run_spec )
76+
77+ job_specs = await configurator .get_job_specs (replica_num = 0 )
78+
79+ assert job_specs [0 ].commands == [expected_shell , "-i" , "-c" , "sleep inf" ]
80+
81+ @pytest .mark .parametrize (
82+ ["shell" , "expected_shell" ],
83+ [
84+ pytest .param (None , "/bin/bash" , id = "default-shell" ),
85+ pytest .param ("sh" , "/bin/sh" , id = "sh" ),
86+ pytest .param ("bash" , "/bin/bash" , id = "bash" ),
87+ pytest .param ("/usr/bin/zsh" , "/usr/bin/zsh" , id = "custom-shell" ),
88+ ],
89+ )
90+ async def test_with_commands_no_image (self , shell : Optional [str ], expected_shell : str ):
91+ configuration = TaskConfiguration (commands = ["sleep inf" ], shell = shell )
92+ run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
93+ configurator = TaskJobConfigurator (run_spec )
94+
95+ job_specs = await configurator .get_job_specs (replica_num = 0 )
96+
97+ assert job_specs [0 ].commands == [expected_shell , "-i" , "-c" , "sleep inf" ]
98+
99+ async def test_no_commands (self , image_config_mock : ImageConfig ):
100+ image_config_mock .entrypoint = ["/entrypoint.sh" ]
101+ image_config_mock .cmd = ["-f" , "-x" ]
102+ configuration = TaskConfiguration (image = "debian" )
103+ run_spec = get_run_spec (run_name = "run" , repo_id = "id" , configuration = configuration )
104+ configurator = TaskJobConfigurator (run_spec )
105+
106+ job_specs = await configurator .get_job_specs (replica_num = 0 )
107+
108+ assert job_specs [0 ].commands == ["/entrypoint.sh" , "-f" , "-x" ]
0 commit comments