Skip to content

Commit 7bbe46d

Browse files
Pigbibicodex
andcommitted
fix: reject ambiguous scheduler cron
Co-Authored-By: Codex <noreply@openai.com>
1 parent 5885c9b commit 7bbe46d

4 files changed

Lines changed: 53 additions & 1 deletion

File tree

.github/workflows/sync-cloud-run-env.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,10 @@ jobs:
992992
if len(time_fields) == 5:
993993
print(" ".join(time_fields))
994994
elif len(time_fields) == 2:
995+
if current_fields[2] != "*" and current_fields[4] != "*":
996+
raise SystemExit(
997+
"Cloud Scheduler schedule cannot constrain both day-of-month and day-of-week"
998+
)
995999
print(" ".join([*time_fields, *current_fields[2:]]))
9961000
else:
9971001
raise SystemExit(

scripts/build_cloud_run_env_sync_plan.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,23 @@ def _build_scheduler_plan(
480480
per_service_mode=per_service_mode,
481481
allow_shared_fallback=True,
482482
)
483-
scheduler[key] = str(runtime_scheduler.get(key) or configured_value or SCHEDULER_TIME_DEFAULTS[key])
483+
scheduler[key] = _validate_scheduler_time(
484+
key,
485+
str(runtime_scheduler.get(key) or configured_value or SCHEDULER_TIME_DEFAULTS[key]),
486+
)
484487
return scheduler
485488

486489

490+
def _validate_scheduler_time(name: str, value: str) -> str:
491+
fields = value.split()
492+
if len(fields) == 5 and fields[2] != "*" and fields[4] != "*":
493+
raise ValueError(
494+
f"{name} cannot constrain both day-of-month and day-of-week; "
495+
"Cloud Scheduler applies OR semantics to those fields"
496+
)
497+
return value
498+
499+
487500
def _validate_profile_inputs(
488501
*,
489502
service_name: str,

tests/test_build_cloud_run_env_sync_plan.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,34 @@ def test_build_cloud_run_env_sync_plan_legacy_mode_uses_shared_env():
8282
}
8383

8484

85+
def test_build_cloud_run_env_sync_plan_rejects_ambiguous_cloud_scheduler_cron():
86+
env = {
87+
**os.environ,
88+
"CLOUD_RUN_SERVICE": "longbridge-quant-paper-service",
89+
"GLOBAL_TELEGRAM_CHAT_ID": "5992562050",
90+
"NOTIFY_LANG": "zh",
91+
"ACCOUNT_PREFIX": "PAPER",
92+
"RUNTIME_TARGET_JSON": runtime_target_json(
93+
"soxl_soxx_trend_income",
94+
deployment_selector="PAPER",
95+
account_scope="PAPER",
96+
service_name="longbridge-quant-paper-service",
97+
),
98+
"LONGBRIDGE_MARKET": "US",
99+
"CLOUD_SCHEDULER_PROBE_TIME": "35 9 1-7 * 1-5",
100+
}
101+
102+
result = subprocess.run(
103+
[sys.executable, str(SYNC_PLAN_SCRIPT_PATH), "--json"],
104+
capture_output=True,
105+
text=True,
106+
env=env,
107+
)
108+
109+
assert result.returncode != 0
110+
assert "cannot constrain both day-of-month and day-of-week" in result.stderr
111+
112+
85113
def test_build_cloud_run_env_sync_plan_requires_target_snapshot_in_per_service_mode():
86114
payload = {
87115
"defaults": {

tests/test_scheduler_workflow.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ def test_replacement_probe_and_precheck_exist_before_shared_dispatcher_cleanup()
1717
assert "environment: longbridge-sg" in cleanup_section
1818
assert 'replacement_jobs=("${service_name}-probe-scheduler" "${service_name}-precheck-scheduler")' in cleanup_section
1919
assert "if: steps.replacements.outputs.ready == 'true'" in cleanup_section
20+
21+
22+
def test_existing_scheduler_cron_rejects_ambiguous_day_fields() -> None:
23+
workflow = Path(".github/workflows/sync-cloud-run-env.yml").read_text(encoding="utf-8")
24+
25+
assert 'if current_fields[2] != "*" and current_fields[4] != "*":' in workflow
26+
assert "cannot constrain both day-of-month and day-of-week" in workflow

0 commit comments

Comments
 (0)