diff --git a/.github/workflows/sync-cloud-run-env.yml b/.github/workflows/sync-cloud-run-env.yml index b557559..d120de6 100644 --- a/.github/workflows/sync-cloud-run-env.yml +++ b/.github/workflows/sync-cloud-run-env.yml @@ -1218,25 +1218,33 @@ jobs: --max-retry-duration=0s \ --quiet fi - case "${runtime_target_enabled}" in - 1|true|yes|on) - if [ "${precheck_state}" = "PAUSED" ]; then - gcloud scheduler jobs resume "${precheck_job_name}" \ - --project="${GCP_PROJECT_ID}" \ - --location="${scheduler_location}" \ - --quiet - fi - ;; - *) - if [ "${precheck_state}" != "PAUSED" ]; then - echo "Pausing Cloud Scheduler precheck ${precheck_job_name} because ${cloud_run_service} is disabled." - gcloud scheduler jobs pause "${precheck_job_name}" \ - --project="${GCP_PROJECT_ID}" \ - --location="${scheduler_location}" \ - --quiet - fi - ;; - esac + managed_scheduler_jobs=("${job_name}" "${warmup_job_name}" "${precheck_job_name}") + for managed_job_name in "${managed_scheduler_jobs[@]}"; do + managed_job_state="$(gcloud scheduler jobs describe "${managed_job_name}" \ + --project="${GCP_PROJECT_ID}" \ + --location="${scheduler_location}" \ + --format='value(state)')" + case "${runtime_target_enabled}" in + 1|true|yes|on) + if [ "${managed_job_state}" = "PAUSED" ]; then + echo "Resuming Cloud Scheduler job ${managed_job_name} because ${cloud_run_service} is enabled." + gcloud scheduler jobs resume "${managed_job_name}" \ + --project="${GCP_PROJECT_ID}" \ + --location="${scheduler_location}" \ + --quiet + fi + ;; + *) + if [ "${managed_job_state}" != "PAUSED" ]; then + echo "Pausing Cloud Scheduler job ${managed_job_name} because ${cloud_run_service} is disabled." + gcloud scheduler jobs pause "${managed_job_name}" \ + --project="${GCP_PROJECT_ID}" \ + --location="${scheduler_location}" \ + --quiet + fi + ;; + esac + done done reconcile_args=( diff --git a/tests/test_scheduler_deadline_contract.py b/tests/test_scheduler_deadline_contract.py index 777f222..7620263 100644 --- a/tests/test_scheduler_deadline_contract.py +++ b/tests/test_scheduler_deadline_contract.py @@ -53,8 +53,7 @@ def test_precheck_uses_per_service_scheduler_with_bounded_deadline() -> None: assert workflow.count("--attempt-deadline=120s") == 2 assert workflow.count("--max-retry-attempts=0") == 2 assert workflow.count("--max-retry-duration=0s") == 2 - assert 'gcloud scheduler jobs resume "${precheck_job_name}"' in workflow - assert 'gcloud scheduler jobs pause "${precheck_job_name}"' in workflow + assert 'managed_scheduler_jobs=("${job_name}" "${warmup_job_name}" "${precheck_job_name}")' in workflow assert 'monitor_job_name="interactive-brokers-monitor-dispatcher-scheduler"' not in workflow assert 'shared_env_pairs+=("IBKR_MONITOR_DISPATCH_TARGETS_JSON=' not in workflow @@ -70,12 +69,22 @@ def test_disabled_target_gets_a_paused_canonical_precheck_before_legacy_cleanup( ensure_precheck = workflow.index('if [ -n "${precheck_state}" ]; then') enabled_state = workflow.index('case "${runtime_target_enabled}" in') - pause_precheck = workflow.index('gcloud scheduler jobs pause "${precheck_job_name}"') + pause_precheck = workflow.index('gcloud scheduler jobs pause "${managed_job_name}"') retire_legacy = workflow.index('python3 scripts/reconcile_cloud_runtime.py "${reconcile_args[@]}"') assert ensure_precheck < enabled_state < pause_precheck < retire_legacy +def test_runtime_target_state_controls_all_per_service_schedulers() -> None: + workflow = WORKFLOW.read_text(encoding="utf-8") + + assert 'managed_scheduler_jobs=("${job_name}" "${warmup_job_name}" "${precheck_job_name}")' in workflow + assert 'for managed_job_name in "${managed_scheduler_jobs[@]}"; do' in workflow + assert 'gcloud scheduler jobs resume "${managed_job_name}"' in workflow + assert 'gcloud scheduler jobs pause "${managed_job_name}"' in workflow + assert 'gcloud scheduler jobs pause "${precheck_job_name}"' not in workflow + + def test_legacy_dispatcher_is_retired_after_replacement_jobs_are_ready() -> None: workflow = WORKFLOW.read_text(encoding="utf-8") diff --git a/tests/test_sync_cloud_run_env_workflow.sh b/tests/test_sync_cloud_run_env_workflow.sh index 43a1c36..cec2359 100644 --- a/tests/test_sync_cloud_run_env_workflow.sh +++ b/tests/test_sync_cloud_run_env_workflow.sh @@ -168,8 +168,10 @@ grep -Fq 'gcloud scheduler jobs create http "${precheck_job_name}"' "$workflow_f test "$(grep -Fc -- '--attempt-deadline=120s' "$workflow_file")" -eq 2 test "$(grep -Fc -- '--max-retry-attempts=0' "$workflow_file")" -eq 2 test "$(grep -Fc -- '--max-retry-duration=0s' "$workflow_file")" -eq 2 -grep -Fq 'gcloud scheduler jobs resume "${precheck_job_name}"' "$workflow_file" -grep -Fq 'gcloud scheduler jobs pause "${precheck_job_name}"' "$workflow_file" +grep -Fq 'managed_scheduler_jobs=("${job_name}" "${warmup_job_name}" "${precheck_job_name}")' "$workflow_file" +grep -Fq 'for managed_job_name in "${managed_scheduler_jobs[@]}"; do' "$workflow_file" +grep -Fq 'gcloud scheduler jobs resume "${managed_job_name}"' "$workflow_file" +grep -Fq 'gcloud scheduler jobs pause "${managed_job_name}"' "$workflow_file" test "$(grep -Fc 'monitor_job_name="interactive-brokers-monitor-dispatcher-scheduler"' "$workflow_file")" -eq 0 grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_TO"' "$workflow_file"