Files
wehub-resource-sync ec2b666284
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:25:13 +08:00

109 lines
3.4 KiB
Python

# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for ReplaySequenceBarrier."""
from __future__ import annotations
import asyncio
from google.adk.workflow.utils._replay_sequence_barrier import ReplaySequenceBarrier
import pytest
@pytest.mark.asyncio
async def test_barrier_initialization():
"""Verifies that barrier initializes sequence index and sets the first event."""
# Given a chronological sequence of completions
sequence = ['NodeA@1', 'NodeB@1']
# When barrier is created
barrier = ReplaySequenceBarrier(sequence)
# Then state is correctly set
assert barrier.sequence == sequence
assert barrier.current_index == 0
assert len(barrier.events) == 2
assert barrier.events['NodeA@1'].is_set()
assert not barrier.events['NodeB@1'].is_set()
@pytest.mark.asyncio
async def test_barrier_wait_blocks_and_unblocks():
"""Verifies that wait blocks on subsequent keys and is unblocked by advance."""
sequence = ['NodeA@1', 'NodeB@1']
barrier = ReplaySequenceBarrier(sequence)
# When first key waits, it completes instantly
await barrier.wait('NodeA@1')
# When second key waits, it blocks
b_completed = False
async def wait_b():
nonlocal b_completed
await barrier.wait('NodeB@1')
b_completed = True
task = asyncio.create_task(wait_b())
await asyncio.sleep(0.05)
assert not b_completed # Still blocked
# When first key advances the sequence
barrier.check_and_advance('NodeA@1')
# Then index progresses and second event is released
await task
assert b_completed
assert barrier.current_index == 1
assert barrier.events['NodeB@1'].is_set()
def test_barrier_advance_out_of_order_ignored():
"""Verifies that out-of-order advance calls are ignored and do not progress index."""
sequence = ['NodeA@1', 'NodeB@1']
barrier = ReplaySequenceBarrier(sequence)
# When second key tries to advance out of order
barrier.check_and_advance('NodeB@1')
# Then state remains unchanged
assert barrier.current_index == 0
assert not barrier.events['NodeB@1'].is_set()
@pytest.mark.asyncio
async def test_barrier_wait_non_existent_key():
"""Verifies that waiting on a key not in sequence does not block."""
sequence = ['NodeA@1']
barrier = ReplaySequenceBarrier(sequence)
# When a key not in sequence waits, it passes instantly
await barrier.wait('NonExistent@1')
# No blocks, successfully completes!
assert True
@pytest.mark.asyncio
async def test_barrier_wait_timeout_on_divergence():
"""Verifies that waiting on a blocked key raises RuntimeError due to timeout."""
# We use a short sequence where NodeB is never unblocked
sequence = ['NodeA@1', 'NodeB@1']
# Use a fast timeout to keep the test rapid without mocking standard library functions
barrier = ReplaySequenceBarrier(sequence, timeout_sec=0.01)
with pytest.raises(RuntimeError, match='Replay divergence detected'):
await barrier.wait('NodeB@1')