Exemple #1
0
 async def main(ctx):
     from asyncgui.structured_concurrency import or_
     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 or_(task_a, task_b, task_c)
     elif n_exceptions:
         with pytest.raises(ag.MultiError) as excinfo:
             await or_(task_a, task_b, task_c)
         assert [ZeroDivisionError, ] * n_exceptions == \
             [type(e) for e in excinfo.value.exceptions]
     else:
         await or_(task_a, task_b, task_c)
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
Exemple #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_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_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
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_cancel_without_start():
    from inspect import getcoroutinestate, CORO_CLOSED
    import asyncgui as ag
    task = ag.Task(ag.sleep_forever())
    task.cancel()
    assert task.cancelled
    assert task._exception is None
    assert getcoroutinestate(task.root_coro) == CORO_CLOSED
Exemple #8
0
def test_cancel_all_children():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_
    TS = ag.TaskState

    async def main():
        tasks = await or_(child1, child2)
        for task in tasks:
            assert task.cancelled

    child1 = ag.Task(ag.sleep_forever())
    child2 = ag.Task(ag.sleep_forever())
    main_task = ag.start(main())
    assert main_task.state is TS.STARTED
    child1.cancel()
    assert main_task.state is TS.STARTED
    child2.cancel()
    assert main_task.state is TS.DONE
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_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
Exemple #13
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
Exemple #15
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
Exemple #16
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
Exemple #17
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
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
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
def test_weakref():
    import weakref
    import asyncgui as ag
    task = ag.Task(ag.sleep_forever())
    weakref.ref(task)
    task.cancel()