Skip to content

Commit 2dab4d8

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

2 files changed

Lines changed: 66 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 ExecutionSummary:
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.total_nodes > 0 and 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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from cloud_pipelines_backend import backend_types_sql as bts
2+
from cloud_pipelines_backend.api_server_sql import ExecutionSummary
3+
4+
5+
class TestExecutionSummary:
6+
def test_initial_state(self):
7+
summary = ExecutionSummary()
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 one by one, confirming counts after each."""
14+
summary = ExecutionSummary()
15+
ended_statuses = sorted(bts.CONTAINER_STATUSES_ENDED, key=lambda s: s.value)
16+
for i, status in enumerate(ended_statuses, start=1):
17+
summary.count_node_status(status=status, count=1)
18+
assert summary.total_nodes == i
19+
assert summary.ended_nodes == i
20+
assert summary.has_ended is True
21+
22+
def test_accumulate_all_in_progress_statuses(self):
23+
"""Add each in-progress status one by one, confirming counts after each."""
24+
summary = ExecutionSummary()
25+
in_progress_statuses = sorted(
26+
set(bts.ContainerExecutionStatus) - bts.CONTAINER_STATUSES_ENDED,
27+
key=lambda s: s.value,
28+
)
29+
for i, status in enumerate(in_progress_statuses, start=1):
30+
summary.count_node_status(status=status, count=1)
31+
assert summary.total_nodes == i
32+
assert summary.ended_nodes == 0
33+
assert summary.has_ended is False
34+
35+
def test_accumulate_all_statuses(self):
36+
"""Add every ContainerExecutionStatus one by one, confirming counts after each."""
37+
summary = ExecutionSummary()
38+
all_statuses = sorted(bts.ContainerExecutionStatus, key=lambda s: s.value)
39+
expected_total = 0
40+
expected_ended = 0
41+
for status in all_statuses:
42+
expected_total += 1
43+
if status in bts.CONTAINER_STATUSES_ENDED:
44+
expected_ended += 1
45+
summary.count_node_status(status=status, count=1)
46+
assert summary.total_nodes == expected_total
47+
assert summary.ended_nodes == expected_ended
48+
assert summary.has_ended == (
49+
expected_total > 0 and expected_ended == expected_total
50+
)

0 commit comments

Comments
 (0)