Skip to content

Commit 8d53f38

Browse files
committed
refactor: Enhance TPU info CLI validation by updating command output handling and pattern matching
1 parent 00cf339 commit 8d53f38

2 files changed

Lines changed: 41 additions & 42 deletions

File tree

dags/tpu_observability/tpu_info_format_validation_dags.py

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -274,24 +274,24 @@ def validate_latency_table(tpu_info_output: list[tpu_info.Table]):
274274

275275

276276
@task
277-
def validate_tpu_info_cli(info: node_pool.Info, pod_name: str) -> None:
278-
"""Validates tpu-info CLI commands using the consolidated utility."""
279-
validation_spec = {
280-
tpu_info.TpuInfoCmd.HELP: ["--streaming", "--rate RATE"],
281-
tpu_info.TpuInfoCmd.VERSION: ["tpu-info version:", "libtpu version:"],
282-
tpu_info.TpuInfoCmd.PROCESS: ["TPU Process Info", "/dev/vfio/", "python"],
277+
def validate_tpu_info_patterns(output: str, cmd_name: str):
278+
"""Matches output against patterns defined in a local spec."""
279+
patterns_map = {
280+
tpu_info.TpuInfoCmd.HELP.value: ["--streaming", "--rate RATE"],
281+
tpu_info.TpuInfoCmd.VERSION.value: [
282+
"tpu-info version:",
283+
"libtpu version:",
284+
],
285+
tpu_info.TpuInfoCmd.PROCESS.value: [
286+
"TPU Process Info",
287+
"/dev/vfio/",
288+
"python",
289+
],
283290
}
284-
285-
for cmd_enum, patterns in validation_spec.items():
286-
output = tpu_info.get_tpu_info_from_pod(
287-
info, pod_name, cmd_str=cmd_enum.value
288-
)
289-
290-
for pattern in patterns:
291-
if pattern not in output:
292-
raise AssertionError(
293-
f"Validation failed for '{cmd_enum.value}': Missing pattern '{pattern}'."
294-
)
291+
patterns = patterns_map.get(cmd_name, [])
292+
for pattern in patterns:
293+
if pattern not in output:
294+
raise AssertionError(f"Cmd '{cmd_name}' missing pattern: {pattern}")
295295

296296

297297
# Keyword arguments are generated dynamically at runtime (pylint does not
@@ -428,7 +428,20 @@ def generate_second_node_pool_name(
428428
task_id="get_each_metric_table"
429429
)
430430
.partial()
431-
.expand(output=outputs_of_tpu_info)
431+
.expand(output=raw_metric_data.map(lambda x: x["output"]))
432+
)
433+
434+
cli_raw_results = (
435+
tpu_info.get_tpu_info_from_pod.override(task_id="get_cli_output")
436+
.partial(info=cluster_info)
437+
.expand(
438+
pod_name=pod_names,
439+
cmd_str=[
440+
tpu_info.TpuInfoCmd.HELP.value,
441+
tpu_info.TpuInfoCmd.VERSION.value,
442+
tpu_info.TpuInfoCmd.PROCESS.value,
443+
],
444+
)
432445
)
433446

434447
# Keyword arguments are generated dynamically at runtime (pylint does not
@@ -468,11 +481,9 @@ def generate_second_node_pool_name(
468481
.expand(tpu_info_output=output_of_tpu_info)
469482
)
470483

471-
cli_validation = (
472-
validate_tpu_info_cli.override(task_id="validate_tpu_info_cli")
473-
.partial(info=cluster_info)
474-
.expand(pod_name=pod_names)
475-
)
484+
cli_validation = validate_tpu_info_patterns.override(
485+
task_id="validate_cli_output"
486+
).expand_kwargs(cli_raw_results)
476487

477488
clean_up_workload = jobset.end_workload.override(
478489
task_id="clean_up_workload", trigger_rule=TriggerRule.ALL_DONE
@@ -528,8 +539,9 @@ def generate_second_node_pool_name(
528539
apply_time,
529540
running_pods,
530541
wait_for_job_start,
531-
outputs_of_tpu_info,
542+
raw_metric_data,
532543
output_of_tpu_info,
544+
cli_raw_results,
533545
verification_group,
534546
clean_up_workload,
535547
cleanup_node_pool,

dags/tpu_observability/utils/tpu_info_util.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,34 +111,21 @@ def parse_tpu_info_output(output: str) -> list[Table]:
111111
return parsed_tables
112112

113113

114+
@task
114115
def get_tpu_info_from_pod(
115116
info: node_pool.Info, pod_name: str, cmd_str: str
116-
) -> str:
117-
"""
118-
Executes a command (default: tpu-info) in a specified pod
119-
and returns its output.
120-
121-
Consolidated version that handles both standard tpu-info calls and
122-
specific CLI flag validation.
123-
"""
117+
) -> dict:
118+
"""Executes command and returns a dict containing metadata."""
124119
with tempfile.NamedTemporaryFile() as temp_config_file:
125120
env = os.environ.copy()
126121
env["KUBECONFIG"] = temp_config_file.name
127-
128122
cmd = " && ".join([
129123
jobset.Command.get_credentials_command(info),
130124
f"kubectl exec {pod_name} -n default -- {cmd_str}",
131125
])
126+
output = subprocess.run_exec(cmd, env=env)
132127

133-
return subprocess.run_exec(cmd, env=env)
134-
135-
136-
@task
137-
def get_tpu_info_from_pod_task(
138-
info: node_pool.Info, pod_name: str, cmd_str: str
139-
) -> str:
140-
"""Airflow task wrapper for get_tpu_info_from_pod."""
141-
return get_tpu_info_from_pod(info, pod_name, cmd_str)
128+
return {"output": output, "cmd_name": cmd_str}
142129

143130

144131
if __name__ == "__main__":

0 commit comments

Comments
 (0)