@@ -581,3 +581,120 @@ def test_group_env_vars_integration(self):
581581
582582 # The template should include group_env_vars for proper env var handling per command
583583 # (The actual env var exports per command happen in the template rendering)
584+
585+ # ------------------------------------------------------------------
586+ # Custom log directory tests (added for log-dir diff)
587+ # ------------------------------------------------------------------
588+
589+ @pytest .fixture ()
590+ def custom_log_request (self ) -> tuple [SlurmRayRequest , str ]:
591+ """Produce a SlurmRayRequest where ``executor.job_details.folder`` is overridden."""
592+ executor = SlurmExecutor (account = "test_account" )
593+ tunnel_mock = Mock (spec = SSHTunnel )
594+ tunnel_mock .job_dir = "/tmp/test_jobs"
595+ executor .tunnel = tunnel_mock
596+
597+ custom_logs_dir = "/custom/logs/location"
598+ executor .job_details .folder = custom_logs_dir
599+
600+ req = SlurmRayRequest (
601+ name = "test-ray-custom-logs" ,
602+ cluster_dir = "/tmp/test_jobs/test-ray-custom-logs" ,
603+ template_name = "ray.sub.j2" ,
604+ executor = executor ,
605+ command_groups = [["head" ], ["echo" , "hello" ]],
606+ launch_cmd = ["sbatch" , "--parsable" ],
607+ )
608+
609+ return req , custom_logs_dir
610+
611+ def test_log_dir_export_and_sbatch_paths (self , custom_log_request ):
612+ """Ensure that LOG_DIR and SBATCH paths use the custom directory when provided."""
613+ req , custom_logs_dir = custom_log_request
614+ script = req .materialize ()
615+
616+ assert f"export LOG_DIR={ custom_logs_dir } " in script
617+ assert f"#SBATCH --output={ custom_logs_dir } /" in script
618+ assert os .path .join (custom_logs_dir , "ray-overlap-1.out" ) in script
619+
620+ def test_default_log_dir_fallback (self ):
621+ """Default behaviour: log paths default to <cluster_dir>/logs when not overridden."""
622+ executor = SlurmExecutor (account = "test_account" )
623+ tunnel_mock = Mock (spec = SSHTunnel )
624+ tunnel_mock .job_dir = "/tmp/test_jobs"
625+ executor .tunnel = tunnel_mock
626+
627+ cluster_dir = "/tmp/test_jobs/default-logs-cluster"
628+ req = SlurmRayRequest (
629+ name = "default-logs-cluster" ,
630+ cluster_dir = cluster_dir ,
631+ template_name = "ray.sub.j2" ,
632+ executor = executor ,
633+ launch_cmd = ["sbatch" , "--parsable" ],
634+ )
635+
636+ script = req .materialize ()
637+ default_logs = os .path .join (cluster_dir , "logs" )
638+ assert f"export LOG_DIR={ default_logs } " in script
639+ assert f"#SBATCH --output={ default_logs } /" in script
640+
641+ def test_default_ray_log_prefix (self ):
642+ """Ensure that default ``ray_log_prefix`` is respected in generated scripts."""
643+ executor = SlurmExecutor (account = "test_account" )
644+ # Default should be "ray-"
645+ assert executor .job_details .ray_log_prefix == "ray-"
646+
647+ # Attach a mock tunnel so that ``materialize`` works without ssh
648+ tunnel_mock = Mock (spec = SSHTunnel )
649+ tunnel_mock .job_dir = "/tmp/test_jobs"
650+ executor .tunnel = tunnel_mock
651+
652+ req = SlurmRayRequest (
653+ name = "default-prefix" ,
654+ cluster_dir = "/tmp/test_jobs/default-prefix" ,
655+ template_name = "ray.sub.j2" ,
656+ executor = executor ,
657+ command_groups = [["head" ], ["echo" , "hi" ]],
658+ launch_cmd = ["sbatch" , "--parsable" ],
659+ )
660+
661+ script = req .materialize ()
662+
663+ # Head / worker / overlap log paths must include the default prefix
664+ assert "ray-head.log" in script
665+ assert "ray-worker-" in script
666+ assert "ray-overlap-" in script
667+ assert "ray-job.log" in script
668+
669+ def test_custom_ray_log_prefix (self ):
670+ """Validate that a custom ``ray_log_prefix`` propagates to all log file names."""
671+ executor = SlurmExecutor (account = "test_account" )
672+ # Override the prefix
673+ custom_prefix = "mycustom-"
674+ executor .job_details .ray_log_prefix = custom_prefix
675+
676+ # Mock tunnel
677+ tunnel_mock = Mock (spec = SSHTunnel )
678+ tunnel_mock .job_dir = "/tmp/test_jobs"
679+ executor .tunnel = tunnel_mock
680+
681+ req = SlurmRayRequest (
682+ name = "custom-prefix-cluster" ,
683+ cluster_dir = "/tmp/test_jobs/custom-prefix-cluster" ,
684+ template_name = "ray.sub.j2" ,
685+ executor = executor ,
686+ command_groups = [["head" ], ["echo" , "hi" ]],
687+ launch_cmd = ["sbatch" , "--parsable" ],
688+ )
689+
690+ script = req .materialize ()
691+
692+ # All log files generated inside the script should use the custom prefix
693+ expected_patterns = [
694+ f"{ custom_prefix } head.log" ,
695+ f"{ custom_prefix } worker-" ,
696+ f"{ custom_prefix } overlap-1.out" ,
697+ f"{ custom_prefix } job.log" ,
698+ ]
699+ for pattern in expected_patterns :
700+ assert pattern in script , f"Log path missing expected prefix pattern: { pattern } "
0 commit comments