|
15 | 15 | """A DAG to test "Jobset Suspended Healthiness" metric.""" |
16 | 16 |
|
17 | 17 | import datetime |
| 18 | +from datetime import timedelta |
18 | 19 |
|
19 | 20 | from airflow import models |
20 | 21 | from airflow.utils.trigger_rule import TriggerRule |
|
24 | 25 | from dags import composer_env |
25 | 26 | from dags.tpu_observability.utils import jobset_util as jobset |
26 | 27 | from dags.tpu_observability.utils import node_pool_util as node_pool |
| 28 | +from dags.common.task_group_with_timeout import TaskGroupWithTimeout |
27 | 29 | from dags.tpu_observability.utils.jobset_util import Workload, JobSetHealthiness |
28 | 30 | from dags.tpu_observability.configs.common import ( |
29 | 31 | MachineConfigMap, |
|
85 | 87 |
|
86 | 88 | # Keyword arguments are generated dynamically at runtime (pylint does not |
87 | 89 | # know this signature). |
88 | | - with TaskGroup( # pylint: disable=unexpected-keyword-arg |
89 | | - group_id=f"v{config.tpu_version.value}" |
| 90 | + with TaskGroupWithTimeout( # pylint: disable=unexpected-keyword-arg |
| 91 | + group_id=f"v{config.tpu_version.value}", |
| 92 | + timeout=timedelta(minutes=90), |
90 | 93 | ): |
91 | 94 | cluster_info = node_pool.build_node_pool_info_from_gcs_yaml( |
92 | 95 | gcs_path=GCS_CONFIG_PATH, |
|
117 | 120 | workload_type=Workload.JAX_TPU_BENCHMARK, |
118 | 121 | ) |
119 | 122 |
|
120 | | - with TaskGroup(group_id="validate_running_metrics") as validate_running: |
121 | | - running_metrics = [ |
122 | | - (JobSetHealthiness.SPECIFIED, jobset_config.replicas), |
123 | | - (JobSetHealthiness.ACTIVE, jobset_config.replicas), |
124 | | - (JobSetHealthiness.READY, jobset_config.replicas), |
125 | | - (JobSetHealthiness.FAILED, 0), |
126 | | - (JobSetHealthiness.SUCCEEDED, 0), |
127 | | - (JobSetHealthiness.SUSPENDED, 0), |
128 | | - ] |
129 | | - for status, expected in running_metrics: |
130 | | - jobset.wait_for_jobset_metrics.override( |
131 | | - task_id=f"wait_{status.value}" |
132 | | - )( |
133 | | - metric_name=status, |
134 | | - expected_value=expected, |
135 | | - node_pool=cluster_info, |
136 | | - jobset_name=jobset_name, |
137 | | - ) |
| 123 | + running_metrics = [ |
| 124 | + (JobSetHealthiness.SPECIFIED, jobset_config.replicas), |
| 125 | + (JobSetHealthiness.ACTIVE, jobset_config.replicas), |
| 126 | + (JobSetHealthiness.READY, jobset_config.replicas), |
| 127 | + (JobSetHealthiness.FAILED, 0), |
| 128 | + (JobSetHealthiness.SUCCEEDED, 0), |
| 129 | + (JobSetHealthiness.SUSPENDED, 0), |
| 130 | + ] |
| 131 | + validate_running_tasks = [] |
| 132 | + for status, expected in running_metrics: |
| 133 | + t = jobset.wait_for_jobset_metrics.override( |
| 134 | + task_id=f"validate_running_wait_{status.value}" |
| 135 | + )( |
| 136 | + metric_name=status, |
| 137 | + expected_value=expected, |
| 138 | + node_pool=cluster_info, |
| 139 | + jobset_name=jobset_name, |
| 140 | + ) |
| 141 | + validate_running_tasks.append(t) |
138 | 142 |
|
139 | 143 | suspend_action = jobset.suspended_jobset.override( |
140 | 144 | task_id="suspend_jobset" |
|
144 | 148 | jobset_name=jobset_name, |
145 | 149 | ) |
146 | 150 |
|
147 | | - with TaskGroup( |
148 | | - group_id="validate_suspended_metrics" |
149 | | - ) as validate_suspended: |
150 | | - suspended_metrics = [ |
151 | | - (JobSetHealthiness.ACTIVE, 0), |
152 | | - (JobSetHealthiness.SUSPENDED, jobset_config.replicas), |
153 | | - ] |
154 | | - for status, expected in suspended_metrics: |
155 | | - jobset.wait_for_jobset_metrics.override( |
156 | | - task_id=f"wait_after_suspend_{status.value}" |
157 | | - )( |
158 | | - metric_name=status, |
159 | | - expected_value=expected, |
160 | | - node_pool=cluster_info, |
161 | | - jobset_name=jobset_name, |
162 | | - ) |
| 151 | + suspended_metrics = [ |
| 152 | + (JobSetHealthiness.ACTIVE, 0), |
| 153 | + (JobSetHealthiness.SUSPENDED, jobset_config.replicas), |
| 154 | + ] |
| 155 | + validate_suspended_tasks = [] |
| 156 | + for status, expected in suspended_metrics: |
| 157 | + t = jobset.wait_for_jobset_metrics.override( |
| 158 | + task_id=f"validate_suspended_wait_after_suspend_{status.value}" |
| 159 | + )( |
| 160 | + metric_name=status, |
| 161 | + expected_value=expected, |
| 162 | + node_pool=cluster_info, |
| 163 | + jobset_name=jobset_name, |
| 164 | + ) |
| 165 | + validate_suspended_tasks.append(t) |
163 | 166 |
|
164 | 167 | resume_action = jobset.resume_jobset.override(task_id="resume_jobset")( |
165 | 168 | node_pool=cluster_info, |
166 | 169 | jobset_config=jobset_config, |
167 | 170 | jobset_name=jobset_name, |
168 | 171 | ) |
169 | 172 |
|
170 | | - with TaskGroup(group_id="inject_and_validate_success") as success_test: |
171 | | - cleanup_for_success = jobset.end_workload.override( |
172 | | - task_id="cleanup_before_success_injection" |
173 | | - )( |
174 | | - node_pool=cluster_info, |
175 | | - jobset_config=jobset_config, |
176 | | - jobset_name=jobset_name, |
177 | | - ) |
178 | | - |
179 | | - start_success_job = jobset.run_workload.override( |
180 | | - task_id="start_success_job" |
181 | | - )( |
182 | | - node_pool=cluster_info, |
183 | | - jobset_config=jobset_config, |
184 | | - jobset_name=jobset_name, |
185 | | - workload_type=SUCCESS_WORKLOAD, |
186 | | - ) |
187 | | - |
188 | | - validate_succeeded_metric = jobset.wait_for_jobset_metrics.override( |
189 | | - task_id="wait_for_succeeded_count" |
190 | | - )( |
191 | | - metric_name=JobSetHealthiness.SUCCEEDED, |
192 | | - expected_value=jobset_config.replicas, |
193 | | - node_pool=cluster_info, |
194 | | - jobset_name=jobset_name, |
195 | | - ) |
| 173 | + cleanup_for_success = jobset.end_workload.override( |
| 174 | + task_id="cleanup_before_success_injection" |
| 175 | + )( |
| 176 | + node_pool=cluster_info, |
| 177 | + jobset_config=jobset_config, |
| 178 | + jobset_name=jobset_name, |
| 179 | + ) |
196 | 180 |
|
197 | | - chain(cleanup_for_success, start_success_job, validate_succeeded_metric) |
| 181 | + start_success_job = jobset.run_workload.override( |
| 182 | + task_id="start_success_job" |
| 183 | + )( |
| 184 | + node_pool=cluster_info, |
| 185 | + jobset_config=jobset_config, |
| 186 | + jobset_name=jobset_name, |
| 187 | + workload_type=SUCCESS_WORKLOAD, |
| 188 | + ) |
198 | 189 |
|
199 | | - with TaskGroup(group_id="inject_and_validate_failure") as failure_test: |
200 | | - cleanup_for_failure = jobset.end_workload.override( |
201 | | - task_id="cleanup_before_failure_injection" |
202 | | - )( |
203 | | - node_pool=cluster_info, |
204 | | - jobset_config=jobset_config, |
205 | | - jobset_name=jobset_name, |
206 | | - ) |
| 190 | + validate_succeeded_metric = jobset.wait_for_jobset_metrics.override( |
| 191 | + task_id="wait_for_succeeded_count" |
| 192 | + )( |
| 193 | + metric_name=JobSetHealthiness.SUCCEEDED, |
| 194 | + expected_value=jobset_config.replicas, |
| 195 | + node_pool=cluster_info, |
| 196 | + jobset_name=jobset_name, |
| 197 | + ) |
207 | 198 |
|
208 | | - start_fail_job = jobset.run_workload.override(task_id="start_fail_job")( |
209 | | - node_pool=cluster_info, |
210 | | - jobset_config=jobset_config, |
211 | | - jobset_name=jobset_name, |
212 | | - workload_type=FAIL_WORKLOAD, |
213 | | - ) |
| 199 | + cleanup_for_failure = jobset.end_workload.override( |
| 200 | + task_id="cleanup_before_failure_injection" |
| 201 | + )( |
| 202 | + node_pool=cluster_info, |
| 203 | + jobset_config=jobset_config, |
| 204 | + jobset_name=jobset_name, |
| 205 | + ) |
214 | 206 |
|
215 | | - validate_failed_metric = jobset.wait_for_jobset_metrics.override( |
216 | | - task_id="wait_for_failed_count" |
217 | | - )( |
218 | | - metric_name=JobSetHealthiness.FAILED, |
219 | | - expected_value=jobset_config.replicas, |
220 | | - node_pool=cluster_info, |
221 | | - jobset_name=jobset_name, |
222 | | - ) |
| 207 | + start_fail_job = jobset.run_workload.override(task_id="start_fail_job")( |
| 208 | + node_pool=cluster_info, |
| 209 | + jobset_config=jobset_config, |
| 210 | + jobset_name=jobset_name, |
| 211 | + workload_type=FAIL_WORKLOAD, |
| 212 | + ) |
223 | 213 |
|
224 | | - chain(cleanup_for_failure, start_fail_job, validate_failed_metric) |
| 214 | + validate_failed_metric = jobset.wait_for_jobset_metrics.override( |
| 215 | + task_id="wait_for_failed_count" |
| 216 | + )( |
| 217 | + metric_name=JobSetHealthiness.FAILED, |
| 218 | + expected_value=jobset_config.replicas, |
| 219 | + node_pool=cluster_info, |
| 220 | + jobset_name=jobset_name, |
| 221 | + ) |
225 | 222 |
|
226 | 223 | cleanup_workload = jobset.end_workload.override( |
227 | 224 | task_id="cleanup_workload", trigger_rule=TriggerRule.ALL_DONE |
|
244 | 241 | jobset_name, |
245 | 242 | create_node_pool, |
246 | 243 | *startup.tasks, |
247 | | - validate_running, |
| 244 | + *validate_running_tasks, |
248 | 245 | suspend_action, |
249 | | - validate_suspended, |
| 246 | + *validate_suspended_tasks, |
250 | 247 | resume_action, |
251 | | - success_test, |
252 | | - failure_test, |
| 248 | + cleanup_for_success, |
| 249 | + ) |
| 250 | + |
| 251 | + chain( |
| 252 | + cleanup_for_success, |
| 253 | + start_success_job, |
| 254 | + validate_succeeded_metric, |
| 255 | + cleanup_for_failure, |
| 256 | + ) |
| 257 | + |
| 258 | + chain( |
| 259 | + cleanup_for_failure, |
| 260 | + start_fail_job, |
| 261 | + validate_failed_metric, |
253 | 262 | cleanup_workload, |
254 | 263 | cleanup_node_pool, |
255 | 264 | ) |
0 commit comments