def test_the_state_and_the_result():
    job_state = 'A'

    async def job():
        nonlocal job_state
        job_state = 'B'
        await ag.sleep_forever()
        job_state = 'C'
        return 'result'

    task = ag.Task(job())
    root_coro = task.root_coro
    assert task.state is TS.CREATED
    assert task._exception is None
    assert job_state == 'A'
    with pytest.raises(ag.InvalidStateError):
        task.result

    ag.start(task)
    assert task.state is TS.STARTED
    assert task._exception is None
    assert job_state == 'B'
    with pytest.raises(ag.InvalidStateError):
        task.result

    with pytest.raises(StopIteration):
        root_coro.send(None)
    assert task.state is TS.DONE
    assert task._exception is None
    assert task.done
    assert not task.cancelled
    assert task.result == 'result'
def test_clear():
    import asyncgui as ag
    e1 = ag.Event()
    e2 = ag.Event()

    async def main():
        nonlocal task_state
        task_state = 'A'
        await e1.wait()
        task_state = 'B'
        await e2.wait()
        task_state = 'C'
        await e1.wait()
        task_state = 'D'

    task_state = None
    ag.start(main())
    assert task_state == 'A'
    e1.set()
    assert task_state == 'B'
    e1.clear()
    e2.set()
    assert task_state == 'C'
    e1.set()
    assert task_state == 'D'
Esempio n. 3
0
def test_nested(set_immediately_1, set_immediately_2):
    import asyncgui as ag
    TS = ag.TaskState

    e1 = ag.Event()
    e2 = ag.Event()
    if set_immediately_1:
        e1.set()
    if set_immediately_2:
        e2.set()

    main_task = ag.Task(main(e1, e2))
    ag.start(main_task)
    main_task.cancel()
    if set_immediately_1 and set_immediately_2:
        # 中断の機会を与えられずに終わる為 DONE
        assert main_task.state is TS.DONE
        return
    assert main_task.state is TS.STARTED
    if set_immediately_1 or set_immediately_2:
        e1.set()
        e2.set()
        assert main_task.state is TS.CANCELLED
        return
    e1.set()
    assert main_task.state is TS.STARTED
    e2.set()
    assert main_task.state is TS.CANCELLED
def test_the_state_and_the_result__ver_uncaught_exception_2():
    '''coro.throw()によって例外を起こした場合'''
    job_state = 'A'

    async def job():
        nonlocal job_state
        job_state = 'B'
        await ag.sleep_forever()
        job_state = 'C'
        return 'result'

    task = ag.Task(job(), name='pytest')
    root_coro = task.root_coro
    assert task.state is TS.CREATED
    assert task._exception is None
    assert job_state == 'A'
    with pytest.raises(ag.InvalidStateError):
        task.result

    ag.start(task)
    assert task.state is TS.STARTED
    assert task._exception is None
    assert job_state == 'B'
    with pytest.raises(ag.InvalidStateError):
        task.result

    with pytest.raises(ZeroDivisionError):
        root_coro.throw(ZeroDivisionError)
    assert task.state is TS.CANCELLED
    assert task._exception is None
    job_state = 'B'
    assert not task.done
    assert task.cancelled
    with pytest.raises(ag.InvalidStateError):
        task.result
Esempio n. 5
0
async def run_awaitable(ag_awaitable, *, task_status=trio.TASK_STATUS_IGNORED):
    '''(experimental)
    Run an asyncgui-flavored awaitable under Trio.

    Usage #1:
        nursery.start_soon(run_awaitable, an_asyncgui_awaitable)

    Usage #2:
        return_value = await run_awaitable(an_asyncgui_awaitable)
    '''
    if not isawaitable(ag_awaitable):
        raise ValueError(f"{ag_awaitable} is not awaitable")
    end_signal = trio.Event()
    try:
        outcome = {}
        wrapper_coro = _ag_awaitable_wrapper(
            outcome,
            end_signal,
            ag_awaitable,
        )
        asyncgui.start(wrapper_coro)
        task_status.started(wrapper_coro)
        await end_signal.wait()
        exception = outcome.get('exception', None)
        if exception is not None:
            raise exception
        if outcome.get('cancelled', False):
            raise CancelledError("Inner task was cancelled")
        return outcome['return_value']
    finally:
        wrapper_coro.close()
def test_the_state_and_the_result__ver_cancel():
    job_state = 'A'

    async def job():
        nonlocal job_state
        job_state = 'B'
        await ag.sleep_forever()
        job_state = 'C'
        return 'result'

    task = ag.Task(job(), name='pytest')
    root_coro = task.root_coro
    assert task.state is TS.CREATED
    assert task._exception is None
    assert job_state == 'A'
    with pytest.raises(ag.InvalidStateError):
        task.result

    ag.start(task)
    assert task.state is TS.STARTED
    assert task._exception is None
    assert job_state == 'B'
    with pytest.raises(ag.InvalidStateError):
        task.result

    root_coro.close()
    assert task.state is TS.CANCELLED
    assert task._exception is None
    assert not task.done
    assert task.cancelled
    with pytest.raises(ag.InvalidStateError):
        task.result
def test_nested_cancel_protection():
    import asyncgui as ag

    async def outer_fn(e):
        async with ag.cancel_protection():
            await inner_fn(e)
        await ag.sleep_forever()
        pytest.fail("Failed to cancel")

    async def inner_fn(e):
        assert task._cancel_protection == 1
        async with ag.cancel_protection():
            assert task._cancel_protection == 2
            await e.wait()
        assert task._cancel_protection == 1

    e = ag.Event()
    task = ag.Task(outer_fn(e))
    assert task._cancel_protection == 0
    ag.start(task)
    assert task._cancel_protection == 2
    task.cancel()
    assert not task.cancelled
    assert not task._is_cancellable
    e.set()
    assert task._cancel_protection == 0
    assert task.cancelled
def test_concurrency():
    import asyncgui as ag
    from asyncgui.testing import open_scheduler

    state = 'started'

    async def state_changer(sleep):
        nonlocal state
        await sleep(0.1)
        state = 'A'
        await sleep(0.1)
        state = 'B'
        await sleep(0.1)
        state = 'C'

    async def state_watcher(sleep):
        await sleep(0.05)
        assert state == 'started'
        await sleep(0.1)
        assert state == 'A'
        await sleep(0.1)
        assert state == 'B'
        await sleep(0.1)
        assert state == 'C'


    with open_scheduler() as (schedulr, sleep):
        task1 = ag.start(state_changer(sleep))
        task2 = ag.start(state_watcher(sleep))
    assert task1.done
    assert task2.done
def test__already_started():
    import asyncgui as ag
    task1 = ag.start(ag.sleep_forever())
    task2 = ag.start(async_fn())
    for task in (task1, task2):
        with pytest.raises(ValueError):
            ag.start(task)
def test_regular_gen():
    import asyncgui as ag

    def regular_gen():
        yield 1

    with pytest.raises(ValueError):
        ag.start(regular_gen())
def test__unsupported_type():
    import asyncgui as ag

    func = lambda: None
    gen = (i for i in range(3))

    for v in (func, gen):
        with pytest.raises(ValueError):
            ag.start(v)
def test_try_to_cancel_self_but_no_opportunity_for_that():
    import asyncgui as ag

    async def async_fn():
        assert not task._is_cancellable
        task.cancel()

    task = ag.Task(async_fn())
    ag.start(task)
    assert task.done
def test__return_value():
    import asyncgui as ag

    task = ag.Task(ag.sleep_forever())
    gen_based_coro = ag.sleep_forever()
    coro = async_fn()

    assert ag.start(task) is task
    for v in (gen_based_coro, coro):
        assert isinstance(ag.start(v), ag.Task)
def test_multiple_tasks():
    import asyncgui as ag
    TS = ag.TaskState
    e = ag.Event()
    task1 = ag.start(e.wait())
    task2 = ag.start(e.wait())
    assert task1.state is TS.STARTED
    assert task2.state is TS.STARTED
    e.set()
    assert task1.state is TS.DONE
    assert task2.state is TS.DONE
def test_cancel_self():
    import asyncgui as ag

    async def async_fn():
        assert not task._is_cancellable
        task.cancel()
        assert task._cancel_called
        await ag.sleep_forever()
        pytest.fail("Failed to cancel")

    task = ag.Task(async_fn())
    ag.start(task)
    assert task.cancelled
    assert task._exception is None
def test_suppress_exception(do_suppress):
    async def job():
        raise ZeroDivisionError

    task = ag.Task(job(), name='pytest')
    task._suppresses_exception = do_suppress
    if do_suppress:
        ag.start(task)
        assert type(task._exception) is ZeroDivisionError
    else:
        with pytest.raises(ZeroDivisionError):
            ag.start(task)
        assert task._exception is None
    assert task.state is TS.CANCELLED
Esempio n. 17
0
def test_例外を起こさない子_を複数持つ親を中断():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_
    TS = ag.TaskState

    async def main():
        await or_(ag.sleep_forever(), ag.sleep_forever())
        pytest.fail()

    main_task = ag.Task(main())
    ag.start(main_task)
    assert main_task.state is TS.STARTED
    main_task.cancel()
    assert main_task.state is TS.CANCELLED
def test_complicated_case(
    starts_immediately,
    what_a_should_do,
    should_b_fail,
    should_c_fail,
):
    import asyncgui as ag

    ctx = {
        'e_begin': ag.Event(),
        'e': ag.Event(),
        'what_a_should_do': what_a_should_do,
        'should_b_fail': should_b_fail,
        'should_c_fail': should_c_fail,
    }
    n_exceptions = 0
    if what_a_should_do == 'fail':
        n_exceptions += 1
    if should_b_fail:
        n_exceptions += 1
    if should_c_fail:
        n_exceptions += 1

    async def main(ctx):
        from asyncgui.structured_concurrency import and_
        task_a = ag.Task(child_a(ctx))
        task_b = ctx['task_b'] = ag.Task(child_b(ctx))
        task_c = ag.Task(child_c(ctx))
        if n_exceptions == 1:
            with pytest.raises(ZeroDivisionError):
                await and_(task_a, task_b, task_c)
            await ag.sleep_forever()
        elif n_exceptions:
            with pytest.raises(ag.MultiError) as excinfo:
                await and_(task_a, task_b, task_c)
            assert [ZeroDivisionError, ] * n_exceptions == \
                [type(e) for e in excinfo.value.exceptions]
            await ag.sleep_forever()
        else:
            await and_(task_a, task_b, task_c)

    if starts_immediately:
        ctx['e_begin'].set()
    ctx['main_task'] = main_task = ag.Task(main(ctx))
    ag.start(main_task)
    if not starts_immediately:
        ctx['e_begin'].set()
    assert main_task._cancel_called
    assert main_task.cancelled
Esempio n. 19
0
def test__get_step_coro(raw):
    import asyncgui as ag
    done = False

    async def job():
        step_coro = await ag.get_step_coro()
        assert callable(step_coro)
        nonlocal done
        done = True

    if raw:
        ag.raw_start(job())
    else:
        ag.start(job())
    assert done
Esempio n. 20
0
def test__get_current_task(raw):
    import asyncgui as ag
    done = False

    async def job():
        task = await ag.get_current_task()
        assert (task is None) if raw else isinstance(task, ag.Task)
        nonlocal done
        done = True

    if raw:
        ag.raw_start(job())
    else:
        ag.start(job())
    assert done
Esempio n. 21
0
    def test_other_child_does_not_fail(self, other_child):
        import asyncgui as ag
        from asyncgui.structured_concurrency import and_

        async def main(e):
            await and_(finish_soon_but_protected(e), other_child(e))
            pytest.fail("Failed to cancel")

        e = ag.Event()
        main_task = ag.Task(main(e))
        ag.start(main_task)
        assert not main_task.cancelled
        main_task.cancel()
        assert not main_task.cancelled
        e.set()
        assert main_task.cancelled
Esempio n. 22
0
    def test_other_child_fails(self, other_child):
        import asyncgui as ag
        from asyncgui.structured_concurrency import or_

        async def main(e):
            with pytest.raises(ZeroDivisionError):
                await or_(finish_soon_but_protected(e), other_child(e))

        e = ag.Event()
        main_task = ag.Task(main(e))
        ag.start(main_task)
        assert not main_task.done
        main_task.cancel()
        assert not main_task.done
        e.set()
        assert main_task.done
Esempio n. 23
0
def test_必ず例外を起こす子_を複数持つ親を中断_2():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_
    TS = ag.TaskState

    async def main():
        await or_(fail_on_cancel(), fail_on_cancel())
        pytest.fail("Failed to cancel")

    main_task = ag.Task(main())
    ag.start(main_task)
    assert main_task.state is TS.STARTED
    with pytest.raises(ag.MultiError) as excinfo:
        main_task.cancel()
    assert [ZeroDivisionError, ZeroDivisionError] == \
        [type(e) for e in excinfo.value.exceptions]
    assert main_task.state is TS.CANCELLED
Esempio n. 24
0
def test_one_child_fails_immediately():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

    async def main():
        with pytest.raises(ZeroDivisionError):
            await or_(fail_immediately())

    main_task = ag.start(main())
    assert main_task.done
Esempio n. 25
0
def test_checkpoint(call_cancel, protect):
    import asyncgui as ag

    async def async_func(ctx):
        if call_cancel:
            ctx['task'].cancel()
        if protect:
            async with ag.cancel_protection():
                await ag.checkpoint()
        else:
            await ag.checkpoint()

    ctx = {}
    ctx['task'] = task = ag.Task(async_func(ctx))
    ag.start(task)
    if (not protect) and call_cancel:
        assert task.cancelled
    else:
        assert task.done
Esempio n. 26
0
def test_no_child():
    import asyncgui as ag
    from asyncgui.structured_concurrency import and_

    async def main():
        tasks = await and_()
        assert len(tasks) == 0

    main_task = ag.start(main())
    assert main_task.done
Esempio n. 27
0
def test_multiple_children_finish_immediately():
    import asyncgui as ag
    from asyncgui.structured_concurrency import and_

    async def main():
        tasks = await and_(finish_immediately(), finish_immediately())
        assert [True, True] == [task.done for task in tasks]

    main_task = ag.start(main())
    assert main_task.done
def test_cancel_protected_self():
    import asyncgui as ag

    async def async_fn():
        task = await ag.get_current_task()
        async with ag.cancel_protection():
            task.cancel()
            await ag.sleep_forever()
        await ag.sleep_forever()
        pytest.fail("Failed to cancel")

    task = ag.Task(async_fn())
    ag.start(task)
    assert not task.cancelled
    assert not task._is_cancellable
    assert task._cancel_protection == 1
    task._step_coro()
    assert task.cancelled
    assert task._cancel_protection == 0
Esempio n. 29
0
def test_no_child():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

    async def main():
        tasks = await or_()
        assert tasks == []

    main_task = ag.start(main())
    assert main_task.done
def test_set_before_task_starts():
    import asyncgui as ag
    e = ag.Event()
    e.set()

    async def main():
        await e.wait()

    task = ag.start(main())
    assert task.done