Skip to content

Commit b6873b2

Browse files
committed
feat: Model to track node states and has_ended flag
1 parent 2f77f36 commit b6873b2

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

cloud_pipelines_backend/api_server_sql.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,22 @@ class ArtifactNodeIdResponse:
475475
id: bts.IdType
476476

477477

478+
@dataclasses.dataclass(kw_only=True)
479+
class ExecutionStatusSummary:
480+
total_nodes: int = 0
481+
ended_nodes: int = 0
482+
has_ended: bool = False
483+
484+
def count_node_status(
485+
self, *, status: bts.ContainerExecutionStatus, count: int
486+
) -> None:
487+
self.total_nodes += count
488+
if status in bts.CONTAINER_STATUSES_ENDED:
489+
self.ended_nodes += count
490+
491+
self.has_ended = self.ended_nodes == self.total_nodes
492+
493+
478494
@dataclasses.dataclass
479495
class GetGraphExecutionStateResponse:
480496
child_execution_status_stats: dict[bts.IdType, dict[str, int]]

tests/test_api_server_sql.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from cloud_pipelines_backend import backend_types_sql as bts
2+
from cloud_pipelines_backend.api_server_sql import ExecutionStatusSummary
3+
4+
5+
class TestExecutionStatusSummary:
6+
def test_initial_state(self):
7+
summary = ExecutionStatusSummary()
8+
assert summary.total_nodes == 0
9+
assert summary.ended_nodes == 0
10+
assert summary.has_ended is False
11+
12+
def test_accumulate_all_ended_statuses(self):
13+
"""Add each ended status with 2^i count for robust uniqueness."""
14+
summary = ExecutionStatusSummary()
15+
ended_statuses = sorted(bts.CONTAINER_STATUSES_ENDED, key=lambda s: s.value)
16+
expected_total = 0
17+
expected_ended = 0
18+
for i, status in enumerate(ended_statuses):
19+
count = 2**i
20+
summary.count_node_status(status=status, count=count)
21+
expected_total += count
22+
expected_ended += count
23+
assert summary.total_nodes == expected_total
24+
assert summary.ended_nodes == expected_ended
25+
assert summary.has_ended is True
26+
27+
def test_accumulate_all_in_progress_statuses(self):
28+
"""Add each in-progress status with 2^i count for robust uniqueness."""
29+
summary = ExecutionStatusSummary()
30+
in_progress_statuses = sorted(
31+
set(bts.ContainerExecutionStatus) - bts.CONTAINER_STATUSES_ENDED,
32+
key=lambda s: s.value,
33+
)
34+
expected_total = 0
35+
for i, status in enumerate(in_progress_statuses):
36+
count = 2**i
37+
summary.count_node_status(status=status, count=count)
38+
expected_total += count
39+
assert summary.total_nodes == expected_total
40+
assert summary.ended_nodes == 0
41+
assert summary.has_ended is False
42+
43+
def test_accumulate_all_statuses(self):
44+
"""Add every status with 2^i count. Summary math must be exact."""
45+
summary = ExecutionStatusSummary()
46+
all_statuses = sorted(bts.ContainerExecutionStatus, key=lambda s: s.value)
47+
expected_total = 0
48+
expected_ended = 0
49+
for i, status in enumerate(all_statuses):
50+
count = 2**i
51+
expected_total += count
52+
if status in bts.CONTAINER_STATUSES_ENDED:
53+
expected_ended += count
54+
summary.count_node_status(status=status, count=count)
55+
assert summary.total_nodes == expected_total
56+
assert summary.ended_nodes == expected_ended
57+
assert summary.has_ended == (expected_ended == expected_total)

0 commit comments

Comments
 (0)