async def test_reporting_on_resource_readiness(resource, settings, registry, indexers, caplog, event_type, handlers, timer): caplog.set_level(logging.DEBUG) operator_indexed = ToggleSet(all) resource_indexed = await operator_indexed.make_toggle() async with timer, async_timeout.timeout(0.5) as timeout: await process_resource_event( lifecycle=all_at_once, registry=registry, settings=settings, resource=resource, indexers=indexers, memories=ResourceMemories(), memobase=Memo(), raw_event={ 'type': event_type, 'object': {} }, event_queue=asyncio.Queue(), operator_indexed=operator_indexed, resource_indexed=resource_indexed, ) assert not timeout.expired assert timer.seconds < 0.2 # asap, nowait assert operator_indexed.is_on() assert set(operator_indexed) == set() # save RAM assert handlers.event_mock.called
async def test_created_empty(fn, expected): toggleset = ToggleSet(fn) assert len(toggleset) == 0 assert set(toggleset) == set() assert Toggle() not in toggleset assert toggleset.is_on() == expected assert toggleset.is_off() == (not expected)
async def test_blocking_when_operator_is_not_ready( resource, settings, registry, indexers, caplog, event_type, handlers, timer): caplog.set_level(logging.DEBUG) operator_indexed = ToggleSet(all) resource_listed = await operator_indexed.make_toggle() resource_indexed = await operator_indexed.make_toggle() with pytest.raises(asyncio.TimeoutError), timer: await asyncio.wait_for(process_resource_event( lifecycle=all_at_once, registry=registry, settings=settings, resource=resource, indexers=indexers, memories=ResourceMemories(), memobase=Memo(), raw_event={'type': event_type, 'object': {}}, event_queue=asyncio.Queue(), operator_indexed=operator_indexed, resource_indexed=resource_indexed, ), timeout=0.2) assert 0.2 < timer.seconds < 0.4 assert operator_indexed.is_off() assert set(operator_indexed) == {resource_listed} assert not handlers.event_mock.called
async def test_unblocking_once_operator_is_ready( resource, settings, registry, indexers, caplog, event_type, handlers, timer): caplog.set_level(logging.DEBUG) async def delayed_readiness(delay: float): await asyncio.sleep(delay) await resource_listed.turn_to(True) operator_indexed = ToggleSet(all) resource_listed = await operator_indexed.make_toggle() resource_indexed = await operator_indexed.make_toggle() with timer: asyncio.create_task(delayed_readiness(0.2)) await process_resource_event( lifecycle=all_at_once, registry=registry, settings=settings, resource=resource, indexers=indexers, memories=ResourceMemories(), memobase=Memo(), raw_event={'type': event_type, 'object': {}}, event_queue=asyncio.Queue(), operator_indexed=operator_indexed, resource_indexed=resource_indexed, ) assert 0.2 < timer.seconds < 0.4 assert operator_indexed.is_on() assert set(operator_indexed) == {resource_listed} assert handlers.event_mock.called
async def test_dropping_an_unexistent_toggle(fn, expected): toggleset = ToggleSet(fn) toggle = Toggle() await toggleset.drop_toggle(toggle) assert len(toggleset) == 0 assert set(toggleset) == set() assert toggle not in toggleset assert toggleset.is_on() == expected assert toggleset.is_off() == (not expected)
async def test_dropping_a_turned_on_toggle(fn, expected): toggleset = ToggleSet(fn) toggle = await toggleset.make_toggle(True) await toggleset.drop_toggle(toggle) assert len(toggleset) == 0 assert set(toggleset) == set() assert toggle not in toggleset assert toggleset.is_on() == expected assert toggleset.is_off() == (not expected)
async def test_making_a_turned_on_toggle(fn): toggleset = ToggleSet(fn) toggle = await toggleset.make_toggle(True) assert len(toggleset) == 1 assert set(toggleset) == {toggle} assert toggle in toggleset assert Toggle() not in toggleset assert toggleset.is_on() == True assert toggleset.is_off() == False
async def test_dropping_multiple_toggles(fn, expected): toggleset = ToggleSet(fn) toggle1 = await toggleset.make_toggle(True) toggle2 = Toggle() await toggleset.drop_toggles([toggle1, toggle2]) assert len(toggleset) == 0 assert set(toggleset) == set() assert toggle1 not in toggleset assert toggle2 not in toggleset assert toggleset.is_on() == expected assert toggleset.is_off() == (not expected)
async def test_waiting_until_off_wakes_when_turned_off(fn, timer): toggleset = ToggleSet(fn) toggle = await toggleset.make_toggle(True) async def delayed_turning_off(delay: float): await asyncio.sleep(delay) await toggle.turn_to(False) with timer: asyncio.create_task(delayed_turning_off(0.05)) await asyncio.wait_for(toggleset.wait_for(False), timeout=1.0) assert toggleset.is_off() assert timer.seconds < 0.5 # approx. 0.05 plus some code overhead
async def test_pausing_waits_until_resumed( resource, namespace, timer, caplog, assert_logs): caplog.set_level(logging.DEBUG) operator_paused = ToggleSet(any) conflicts_found = await operator_paused.make_toggle(True) async def delayed_resuming(delay: float): await asyncio.sleep(delay) await conflicts_found.turn_to(False) with timer: asyncio.create_task(delayed_resuming(0.2)) async with streaming_block( resource=resource, namespace=namespace, operator_paused=operator_paused, ): pass assert timer.seconds >= 0.2 assert timer.seconds <= 0.5 assert_logs([ r"Pausing the watch-stream for", r"Resuming the watch-stream for", ])
async def test_all_toggles_must_be_off_for_anytoggleset_to_be_off(fn): toggleset = ToggleSet(fn) toggle1 = await toggleset.make_toggle(True) toggle2 = await toggleset.make_toggle(True) assert toggleset.is_on() == True assert toggleset.is_off() == False await toggle1.turn_to(False) assert toggleset.is_on() == True assert toggleset.is_off() == False await toggle2.turn_to(False) assert toggleset.is_on() == False assert toggleset.is_off() == True
async def test_turning_a_toggle_off_turns_the_toggleset_off(fn): toggleset = ToggleSet(fn) toggle = await toggleset.make_toggle(True) assert toggleset.is_on() == True assert toggleset.is_off() == False await toggle.turn_to(False) assert toggleset.is_on() == False assert toggleset.is_off() == True
async def test_pausing_is_ignored_if_turned_off( resource, namespace, timer, caplog, assert_logs): caplog.set_level(logging.DEBUG) operator_paused = ToggleSet(any) await operator_paused.make_toggle(False) with timer: async with streaming_block( resource=resource, namespace=namespace, operator_paused=operator_paused, ): pass assert timer.seconds < 0.2 # no waits, exits as soon as possible assert_logs([], prohibited=[ r"Pausing the watch-stream for", r"Resuming the watch-stream for", ])
async def test_pausing_waits_forever_if_not_resumed( resource, namespace, timer, caplog, assert_logs): caplog.set_level(logging.DEBUG) operator_paused = ToggleSet(any) await operator_paused.make_toggle(True) async def do_it(): async with streaming_block( resource=resource, namespace=namespace, operator_paused=operator_paused, ): pass with pytest.raises(asyncio.TimeoutError), timer: await asyncio.wait_for(do_it(), timeout=0.5) assert timer.seconds >= 0.5 assert_logs([ r"Pausing the watch-stream for", ], prohibited=[ r"Resuming the watch-stream for", ])
async def test_waiting_until_off_fails_when_not_turned_off(fn): toggleset = ToggleSet(fn) await toggleset.make_toggle(True) with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(toggleset.wait_for(False), timeout=0.1) assert toggleset.is_on()
async def operator_paused(): return ToggleSet(any)
async def test_secures_against_usage_as_a_boolean(fn): toggle = ToggleSet(fn) with pytest.raises(NotImplementedError): bool(toggle)
async def test_repr_when_named_and_on(fn): toggleset = ToggleSet(fn) await toggleset.make_toggle(True, name='xyz') assert repr(toggleset) == "{<Toggle: xyz: on>}"
async def test_repr_when_unnamed_and_off(fn): toggleset = ToggleSet(fn) await toggleset.make_toggle(False) assert repr(toggleset) == "{<Toggle: off>}"
async def test_repr_when_empty(fn): toggleset = ToggleSet(fn) assert repr(toggleset) == "set()"