@@ -172,6 +172,44 @@ def test_scheduler_aware_required_services_fall_back_to_named_scheduler_describe
172172 assert scheduler_checked is True
173173
174174
175+ def test_scheduler_aware_named_fallback_uses_service_alias (monkeypatch ):
176+ _clear_runtime_env (monkeypatch )
177+ monkeypatch .setenv ("CLOUD_RUN_SERVICE" , "longbridge-quant-hk-service" )
178+ monkeypatch .setattr (
179+ heartbeat ,
180+ "_list_scheduler_jobs" ,
181+ lambda ** _kwargs : (_ for _ in ()).throw (RuntimeError ("cloudscheduler.jobs.list denied" )),
182+ )
183+ requested_job_names = []
184+
185+ def fake_describe_scheduler_job (job_name , ** _kwargs ):
186+ requested_job_names .append (job_name )
187+ if job_name != "longbridge-quant-hk-scheduler" :
188+ return None
189+ return {
190+ "state" : "ENABLED" ,
191+ "schedule" : "45 15 1-7 * *" ,
192+ "timeZone" : "Asia/Hong_Kong" ,
193+ "httpTarget" : {"uri" : "https://longbridge-quant-hk-service.example.run.app/" },
194+ }
195+
196+ monkeypatch .setattr (heartbeat , "_describe_scheduler_job" , fake_describe_scheduler_job )
197+
198+ required , skip_reason , scheduler_checked = heartbeat ._resolve_required_services (
199+ project = "project-1" ,
200+ since = dt .datetime (2026 , 6 , 10 , 0 , 0 , tzinfo = dt .timezone .utc ),
201+ now = dt .datetime (2026 , 6 , 10 , 2 , 0 , tzinfo = dt .timezone .utc ),
202+ )
203+
204+ assert requested_job_names == [
205+ "longbridge-quant-hk-service-scheduler" ,
206+ "longbridge-quant-hk-scheduler" ,
207+ ]
208+ assert required == []
209+ assert skip_reason and "no configured Cloud Scheduler main job was due" in skip_reason
210+ assert scheduler_checked is True
211+
212+
175213def test_main_skips_when_no_scheduler_main_job_is_due (monkeypatch , capsys ):
176214 _clear_runtime_env (monkeypatch )
177215 monkeypatch .setenv ("GCP_PROJECT_ID" , "longbridgequant" )
0 commit comments