acoustic-carpenter-78188
03/03/2026, 11:31 PMdef test_phase_transitions(run_name: str, action_name: str):
"""Test phase transition functionality with a real action."""
print(f"Fetching action: run={run_name}, action={action_name}")
print("-" * 80)
# Get action details directly (ActionDetails.get is sync via @syncify)
details = ActionDetails.get(run_name=run_name, name=action_name)
print(f"✓ Got action: {action_name}")
print(f" Phase: {details.phase}")
print()
print(f"✓ Got action details")
print(f" Total runtime: {details.runtime.total_seconds():.2f}s")
print(f" Attempts: {details.attempts}")
print()
# Test the new functionality
print("=" * 80)
print("TESTING NEW PHASE TRANSITION FUNCTIONALITY")
print("=" * 80)
print()
# Test 1: Get phase transitions
print("1. Testing get_phase_transitions():")
transitions = details.get_phase_transitions()
if transitions:
print(f" ✓ Found {len(transitions)} phase transitions:")
for t in transitions:
duration_sec = t.duration.total_seconds()
end_str = t.end_time.isoformat() if t.end_time else "ongoing"
print(f" - {t.phase.value:25s} {duration_sec:8.2f}s ({t.start_time.isoformat()} -> {end_str})")
else:
print(" ⚠ No phase transitions found (might be an older action or local execution)")
print()
# Test 2: Phase durations property
print("2. Testing phase_durations property:")
durations = details.phase_durations
if durations:
print(f" ✓ Found {len(durations)} phases:")
for phase, duration in durations.items():
print(f" - {phase.value}: {duration.total_seconds():.2f}s")
else:
print(" ⚠ No phase durations available")
print()
# Test 3: Individual phase properties
print("3. Testing individual phase properties:")
phase_checks = [
("queued_time", details.queued_time),
("waiting_for_resources_time", details.waiting_for_resources_time),
("initializing_time", details.initializing_time),
("running_time", details.running_time),
]
for prop_name, value in phase_checks:
if value is not None:
print(f" ✓ {prop_name:30s} = {value.total_seconds():8.2f}s")
else:
print(f" - {prop_name:30s} = None (phase not encountered)")
print()
# Test 4: Rich representation
print("4. Testing rich representation (shows phase_breakdown):")
print("-" * 80)
print(details)
print("-" * 80)
print()
# Verify totals match
if durations:
total_from_phases = sum(d.total_seconds() for d in durations.values())
total_runtime = details.runtime.total_seconds()
diff = abs(total_from_phases - total_runtime)
print(f"5. Verification:")
print(f" Total from phases: {total_from_phases:.2f}s")
print(f" Total runtime: {total_runtime:.2f}s")
print(f" Difference: {diff:.2f}s")
if diff < 1.0: # Allow 1s difference due to rounding
print(" ✓ Totals match!")
else:
print(" ⚠ Totals don't match exactly (might be expected depending on phase transitions)")
print()
print("=" * 80)
print("✓ ALL TESTS COMPLETED")
print("=" * 80)
Result:
```
Fetching action: run=rhn8t2tsh8q5r577797b, action=a0
--------------------------------------------------------------------------------
✓ Got action: a0
Phase: ActionPhase.SUCCEEDED
✓ Got action details
Total runtime: 32.17s
Attempts: 1
================================================================================
TESTING NEW PHASE TRANSITION FUNCTIONALITY
================================================================================
1. Testing get_phase_transitions():
✓ Found 4 phase transitions:
- waiting_for_resources 4.15s (2026-02-25T161117.895057+00:00 -> 2026-02-25T161122.040876+00:00)
- queued 0.04s (2026-02-25T161122.040876+00:00 -> 2026-02-25T161122.076044+00:00)
- running 28.27s (2026-02-25T161122.076044+00:00 -> 2026-02-25T161150.342616+00:00)
- succeeded 0.00s (2026-02-25T161150.342616+00:00 -> 2026-02-25T161150.342616+00:00)
2. Testing phase_durations property:
✓ Found 4 phases:
- waiting_for_resources: 4.15s
- queued: 0.04s
- running: 28.27s
- succeeded: 0.00s
3. Testing individual phase properties:
✓ queued_time = 0.04s
✓ waiting_for_resources_time = 4.15s
- initializing_time = None (phase not encountered)
✓ running_time = 28.27s
4. Testing rich representation (shows phase_breakdown):
--------------------------------------------------------------------------------
ActionDetails(
name='rhn8t2tsh8q5r577797b',
start_time='2026-02-25T161117.831931+00:00',
end_time='2026-02-25T161150+00:00',
run_time='32 secs',
phase='ACTION_PHASE_SUCCEEDED',
error='NA',
task='flyte_v2.flyte_workflow',
task_type='actor',
task_version='0a4a8514cee73446310d19f03a499ec3',
attempts=[phase: ACTION_PHASE_SUCCEEDED
start_time {
seconds: 1772035877
nanos: 895057472
}
end_time {
seconds: 1772035910
nanos: 342616457
}
attempt: 1
log_info {
uri: "https://us-east-2.console.aws.amazon.com/cloudwatch/home?region=us-east-2#logsV2:log-groups/log-group/$252Funion$252Fcluster-oc-production$252Ftask/log-events/kube.namespace-daniel-development.pod-flyte-v2-5d469e4d87e6.cont-flyte-v2-5d469e4d87e6$3Fstart$3D1772035882040$26end$3D1772035910342"
name: "Cloudwatch Logs"
ready: true
}
outputs {
output_uri: "s3://union-oc-production-demo/metadata/v2/demo/daniel/development/rhn8t2tsh8q5r577797b/a0/1/outputs.pb"
}
logs_available: true
cluster_events {
occurred_at {
seconds: 1772035877
nanos: 895057472
}
message: "no workers available"
}
cluster_events {
occurred_at {
seconds: 1772035882
nanos: 40876163
}
message: "task offered to worker flyte-v2-5d469e4d87e6"
}
phase_transitions {
phase: ACTION_PHASE_WAITING_FOR_RESOURCES
start_time {
seconds: 1772035877
nanos: 895057472
}
end_time {
seconds: 1772035882
nanos: 40876163
}
}
phase_transitions {
phase: ACTION_PHASE_QUEUED
start_time {
seconds: 1772035882
nanos: 40876163
}
end_time {
seconds: 1772035882
nanos: 76044300
}
}
phase_transitions {
phase: ACTION_PHASE_RUNNING
start_time {
seconds: 1772035882
nanos: 76044300
}
end_time {
seconds: 1772035910
nanos: 342616457
}
}
phase_transitions {
phase: ACTION_PHASE_SUCCEEDED
start_time {
seconds: 1772035910
nanos: 342616457
}
end_time {
seconds: 1772035910
nanos: 342616457
}
}
cluster: "oc-production"
log_context {
pods {
namespace: "daniel-development"
pod_name: "flyte-v2-5d469e4d87e6"
containers {
container_name: "flyte-v2-5d469e4d87e6"
process {
container_start_time {
seconds: 1772035882
nanos: 40813663
}
container_end_time {
seconds: 1772035910
nanos: 342561206
}
}
}
primary_container_name: "flyte-v2-5d469e4d87e6"
}
primary_pod_name: "flyte-v2-5d469e4d87e6"
}
],
error='NA',
phase='ACTION_PHASE_SUCCEEDED',
group='',
parent='',
phase_breakdown={
'waiting_for_resources': '4.15s',
'queued': '0.04s',
'running': '28.27s',
'succeeded': '0.00s'
}
)
--------------------------------------------------------------------------------
5. Verification:
Total from phases: 32.45s
Total runtime: 32.17s
Difference…
flyteorg/flyte-sdkacoustic-carpenter-78188
03/04/2026, 1:06 AM