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'
예제 #2
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
예제 #3
0
def test_complicated_case(
    starts_immediately,
    what_a_should_do,
    should_b_fail,
    should_c_fail,
):
    import asyncgui as ag
    TS = ag.TaskState

    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)
        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]
        else:
            await and_(task_a, task_b, task_c)

    if starts_immediately:
        ctx['e_begin'].set()
    main_task = ag.start(main(ctx))
    if not starts_immediately:
        ctx['e_begin'].set()
    if should_c_fail or should_b_fail or what_a_should_do != 'suspend':
        assert main_task.state is TS.DONE
    else:
        assert main_task.state is TS.STARTED
        main_task.cancel()
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_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
def test_pass_argument():
    import asyncgui as ag
    e = ag.Event()

    async def main(e):
        assert await e.wait() == 'A'

    task = ag.start(main(e))
    assert not task.done
    e.set('A')
    assert task.done
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
예제 #8
0
def test_one_child_fails_soon():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

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

    e = ag.Event()
    main_task = ag.start(main(e))
    assert not main_task.done
    e.set()
    assert main_task.done
예제 #9
0
def test_multiple_children_finish_soon():
    import asyncgui as ag
    from asyncgui.structured_concurrency import and_

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

    e = ag.Event()
    main_task = ag.start(main(e))
    assert not main_task.done
    e.set()
    assert main_task.done
예제 #10
0
def test_multiple_children_finish_soon():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_
    TS = ag.TaskState

    async def main(e):
        tasks = await or_(finish_soon(e), finish_soon(e))
        assert [TS.DONE, TS.CANCELLED] == [task.state for task in tasks]

    e = ag.Event()
    main_task = ag.start(main(e))
    assert not main_task.done
    e.set()
    assert main_task.done
예제 #11
0
def test_one_child_finishes_soon():
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

    async def main(e):
        tasks = await or_(finish_soon(e))
        assert [
            True,
        ] == [task.done for task in tasks]

    e = ag.Event()
    main_task = ag.start(main(e))
    assert not main_task.done
    e.set()
    assert main_task.done
예제 #12
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
예제 #13
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
예제 #14
0
def test_multiple_children_fail_soon():
    '''
    MultiErrorが起こるように思えるが、1つ目の子で例外が起こるや否や2つ目
    は即中断されるため、2つ目では例外は起こらない
    '''
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

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

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

    async def main(e):
        with pytest.raises(ag.MultiError) as excinfo:
            await or_(fail_on_cancel(), fail_on_cancel())
        assert [ZeroDivisionError, ZeroDivisionError] == \
            [type(e) for e in excinfo.value.exceptions]
        await e.wait()
        pytest.fail("Failed to cancel")

    e = ag.Event()
    main_task = ag.Task(main(e))
    ag.start(main_task)
    assert main_task.state is TS.STARTED
    main_task.cancel()
    assert main_task.state is TS.CANCELLED
예제 #16
0
def test_multiple_children_fail():
    '''
    1つ目の子で例外が起こる事で2つ目が中断される。その時2つ目でも例外が
    起きるためMultiErrorが湧く。
    '''
    import asyncgui as ag
    from asyncgui.structured_concurrency import or_

    async def main(e):
        with pytest.raises(ag.MultiError) as excinfo:
            await or_(fail_soon(e), fail_on_cancel())
        assert [ZeroDivisionError, ZeroDivisionError] == \
            [type(e) for e in excinfo.value.exceptions]

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

    async def job1(e):
        assert await e.wait() == 'A'
        e.clear()
        e.set('B')

    async def job2(e):
        assert await e.wait() == 'A'
        assert await e.wait() == 'B'

    task1 = ag.start(job1(e))
    task2 = ag.start(job2(e))
    assert not task1.done
    assert not task2.done
    e.set('A')
    assert task1.done
    assert task2.done
def test_callback():
    import asyncgui as ag
    e = ag.Event()

    def callback(value):
        assert value == 'A'
        nonlocal done
        done = True

    # set after a callback is registered
    done = False
    e.add_callback(callback)
    assert not done
    e.set('A')
    assert done
    e.clear()

    # set before a callback is registered
    done = False
    e.set('A')
    assert not done
    e.add_callback(callback)
    assert done