@@ -619,54 +619,117 @@ def test_multiple_clones(self, dda, helpers, mocker, temp_dir, host_user_args):
619619 ]
620620
621621 @pytest .mark .parametrize (
622- ("volume_mount_specs" , "result_mounts " ),
622+ ("volume_specs " ),
623623 [
624- # Case 1: -v, Single absolute path
625- pytest .param (
626- ["-v" , "/tmp/mounted:/tmp/mounted_abs" ],
627- [Mount (type = "bind" , path = "/tmp/mounted_abs" , source = "/tmp/mounted" , read_only = False )],
628- id = "-v, single_absolute_path" ,
629- ),
630- # Case 2: -v, Single relative path
631- pytest .param (
632- ["-v" , "./mounted:/tmp/mounted_rel" ],
633- [Mount (type = "bind" , path = "/tmp/mounted_rel" , source = "./mounted" , read_only = False )],
634- id = "-v, single_relative_path" ,
635- ),
636- # Case 3: -v, --volume, Multiple mounts
637- pytest .param (
638- ["-v" , "/tmp/mounted:/tmp/mounted_abs" , "--volume" , "./mounted:/tmp/mounted_rel" ],
639- [
640- Mount (type = "bind" , path = "/tmp/mounted_abs" , source = "/tmp/mounted" , read_only = False ),
641- Mount (type = "bind" , path = "/tmp/mounted_rel" , source = "./mounted" , read_only = False ),
642- ],
643- id = "-v, --volume, multiple_mounts" ,
624+ # Case 1: Single -v
625+ ["-v" , "/tmp/mounted:/tmp/mounted_abs" ],
626+ # Case 2: Single --volume
627+ ["--volume" , "/tmp/mounted:/tmp/mounted_abs" ],
628+ # Case 3: -v and --volume
629+ ["-v" , "/tmp/mounted:/tmp/mounted_abs" , "--volume" , "./mounted:/tmp/mounted_rel" ],
630+ ],
631+ )
632+ def test_extra_volume_specs (self , dda , helpers , mocker , temp_dir , host_user_args , volume_specs ):
633+ mocker .patch ("dda.utils.ssh.write_server_config" )
634+
635+ # Disable source and destination validation for the extra mount specs
636+ mocker .patch (
637+ "dda.env.dev.types.linux_container.__validate_mount_src_dst" ,
638+ return_value = None ,
639+ )
640+ shared_dir = temp_dir / "data" / "env" / "dev" / "linux-container" / ".shared"
641+ starship_mount = get_starship_mount (shared_dir )
642+ cache_volumes = get_cache_volumes ()
643+
644+ with (
645+ temp_dir .as_cwd (),
646+ helpers .hybrid_patch (
647+ "subprocess.run" ,
648+ return_values = {
649+ # Start command checks the status
650+ 1 : CompletedProcess ([], returncode = 0 , stdout = "{}" ),
651+ # Start method checks the status
652+ 2 : CompletedProcess ([], returncode = 0 , stdout = "{}" ),
653+ # Capture container run
654+ # Readiness check
655+ 4 : CompletedProcess ([], returncode = 0 , stdout = "Server listening on :: port 22" ),
656+ # Repo cloning
657+ 5 : CompletedProcess ([], returncode = 0 , stdout = "{}" ),
658+ },
659+ ) as calls ,
660+ ):
661+ result = dda ("env" , "dev" , "start" , "--no-pull" , "--clone" , * volume_specs )
662+
663+ result .check (
664+ exit_code = 0 ,
665+ output = helpers .dedent (
666+ """
667+ Creating and starting container: dda-linux-container-default
668+ Waiting for container: dda-linux-container-default
669+ Cloning repository: datadog-agent
670+ """
644671 ),
645- # Case 4: -v, mount with ro flag
646- pytest .param (
647- ["-v" , "/tmp/mounted:/tmp/mounted_abs:ro" ],
648- [
649- Mount (type = "bind" , path = "/tmp/mounted_abs" , source = "/tmp/mounted" , read_only = True ),
650- ],
651- id = "-v, mount_with_ro" ,
672+ )
673+ assert calls == [
674+ (
675+ (
676+ [
677+ helpers .locate ("docker" ),
678+ "run" ,
679+ "--pull" ,
680+ "never" ,
681+ "-d" ,
682+ "--name" ,
683+ "dda-linux-container-default" ,
684+ "-p" ,
685+ "61938:22" ,
686+ "-p" ,
687+ "50069:9000" ,
688+ "-v" ,
689+ "/var/run/docker.sock:/var/run/docker.sock" ,
690+ * host_user_args ,
691+ "-e" ,
692+ "DD_SHELL" ,
693+ "-e" ,
694+ AppEnvVars .TELEMETRY_API_KEY ,
695+ "-e" ,
696+ AppEnvVars .TELEMETRY_USER_MACHINE_ID ,
697+ "-e" ,
698+ GitEnvVars .AUTHOR_NAME ,
699+ "-e" ,
700+ GitEnvVars .AUTHOR_EMAIL ,
701+ * starship_mount ,
702+ "-v" ,
703+ f"{ shared_dir / 'shell' / 'zsh' / '.zsh_history' } :/root/.shared/shell/zsh/.zsh_history" ,
704+ * cache_volumes ,
705+ * [(x if x != "-v" else "--volume" ) for x in volume_specs ],
706+ "datadog/agent-dev-env-linux" ,
707+ ],
708+ ),
709+ {"encoding" : "utf-8" , "stdout" : subprocess .PIPE , "stderr" : subprocess .PIPE , "env" : mocker .ANY },
652710 ),
653- # Case 5: -m, single bind mount
711+ ]
712+
713+ @pytest .mark .parametrize (
714+ ("mount_specs" , "result_mounts" ),
715+ [
716+ # Case 1: -m, single bind mount
654717 pytest .param (
655718 ["-m" , "type=bind,src=/tmp/mounted,dst=/tmp/mounted_abs" ],
656719 [
657720 Mount (type = "bind" , path = "/tmp/mounted_abs" , source = "/tmp/mounted" , read_only = False ),
658721 ],
659722 id = "-m, single_bind_mount" ,
660723 ),
661- # Case 6 : -m, single volume mount
724+ # Case 2 : -m, single volume mount
662725 pytest .param (
663726 ["-m" , "type=volume,src=some-volume,dst=/tmp/mounted_abs" ],
664727 [
665728 Mount (type = "volume" , path = "/tmp/mounted_abs" , source = "some-volume" , read_only = False ),
666729 ],
667730 id = "-m, single_volume_mount" ,
668731 ),
669- # Case 7 : -m, mounts with flags
732+ # Case 3 : -m, mounts with flags
670733 pytest .param (
671734 [
672735 "-m" ,
@@ -692,7 +755,7 @@ def test_multiple_clones(self, dda, helpers, mocker, temp_dir, host_user_args):
692755 ],
693756 id = "-m, mounts_with_flags" ,
694757 ),
695- # Case 8 : -m, --mount, multiple mounts with different syntax
758+ # Case 4 : -m, --mount, multiple mounts with different syntax
696759 pytest .param (
697760 [
698761 "-m" ,
@@ -711,7 +774,7 @@ def test_multiple_clones(self, dda, helpers, mocker, temp_dir, host_user_args):
711774 ),
712775 ],
713776 )
714- def test_extra_mounts (self , dda , helpers , mocker , temp_dir , host_user_args , volume_mount_specs , result_mounts ):
777+ def test_extra_mounts (self , dda , helpers , mocker , temp_dir , host_user_args , mount_specs , result_mounts ):
715778 mocker .patch ("dda.utils.ssh.write_server_config" )
716779
717780 # Disable source and destination validation for the extra mount specs
@@ -740,14 +803,7 @@ def test_extra_mounts(self, dda, helpers, mocker, temp_dir, host_user_args, volu
740803 },
741804 ) as calls ,
742805 ):
743- result = dda (
744- "env" ,
745- "dev" ,
746- "start" ,
747- "--no-pull" ,
748- "--clone" ,
749- * volume_mount_specs ,
750- )
806+ result = dda ("env" , "dev" , "start" , "--no-pull" , "--clone" , * mount_specs )
751807
752808 result .check (
753809 exit_code = 0 ,
@@ -803,45 +859,6 @@ def test_extra_mounts(self, dda, helpers, mocker, temp_dir, host_user_args, volu
803859 ),
804860 ]
805861
806- @pytest .mark .parametrize (
807- ("volume_spec" , "error_message" ),
808- [
809- pytest .param (
810- "/i/dont/exist:/valid/path" ,
811- "Source must be an existing path on the host." ,
812- id = "absolute_src_does_not_exist" ,
813- ),
814- pytest .param (
815- "./i/dont/exist:/valid/path" ,
816- "Source must be an existing path on the host." ,
817- id = "relative_src_does_not_exist" ,
818- ),
819- pytest .param (
820- "./:dir" ,
821- "Destination must be an absolute path." ,
822- id = "dst_is_not_absolute" ,
823- ),
824- pytest .param (
825- "/tmp:/container:foobar" ,
826- "Invalid volume flag: foobar" ,
827- id = "invalid_arbitrary_flag" ,
828- ),
829- pytest .param (
830- "/tmpcontainer" ,
831- "Expected format:" ,
832- id = "no_colon" ,
833- ),
834- ],
835- )
836- def test_invalid_volume_specs (self , dda , temp_dir , mocker , volume_spec , error_message ):
837- mocker .patch ("subprocess.run" , return_value = CompletedProcess ([], returncode = 0 , stdout = "{}" ))
838-
839- with temp_dir .as_cwd ():
840- result = dda ("env" , "dev" , "start" , "-v" , volume_spec )
841-
842- result .check_exit_code (2 )
843- assert error_message in result .output
844-
845862 @pytest .mark .requires_unix # This fails with Windows-style paths
846863 @pytest .mark .parametrize (
847864 ("mount_spec" , "error_message" ),
0 commit comments