[Python-modules-team] Bug#911607: aiohttp.test_utils setup_test_loop/teardown_test_loop not repeatable

Enrico Zini enrico at debian.org
Mon Oct 22 15:26:28 BST 2018


Package: python3-aiohttp
Version: 3.1.3-1
Severity: normal

Hello,

Thank you for packaging aiohttp for Debian!

I am writing an aiohttp application which also runs child processes
using asyncio.subprocess, and unit testing bits of the application hangs
as soon as more than one test case is run.

I tracked down the problem to setup_test_loop/teardown_test_loop not
working the same way if run repeatedly. I'm attaching a test script:
when run on testing, I get this output:

first setup Ignored: 13, 25
first setup None: 32, 33
first setup 2 <built-in function default_int_handler>
first after set_event_loop Ignored: 13, 25
first after set_event_loop None: 32, 33
first after set_event_loop 2 <built-in function default_int_handler>
first after set_child_watcher Ignored: 13, 25
first after set_child_watcher None: 32, 33
first after set_child_watcher 2 <built-in function default_int_handler>
first after set_child_watcher 17 <function _sighandler_noop at 0x7fb6b6973510>
first setup end Ignored: 13, 25
first setup end None: 32, 33
first setup end 2 <built-in function default_int_handler>
first setup end 17 <function _sighandler_noop at 0x7fb6b6973510>
first teardown end Ignored: 13, 25
first teardown end None: 32, 33
first teardown end 2 <built-in function default_int_handler>
second setup Ignored: 13, 25
second setup None: 32, 33
second setup 2 <built-in function default_int_handler>
second after set_event_loop Ignored: 13, 25
second after set_event_loop None: 32, 33
second after set_event_loop 2 <built-in function default_int_handler>
second after set_event_loop 17 <function _sighandler_noop at 0x7fb6b6973510>
second after set_child_watcher Ignored: 13, 25
second after set_child_watcher None: 32, 33
second after set_child_watcher 2 <built-in function default_int_handler>
second setup end Ignored: 13, 25
second setup end None: 32, 33
second setup end 2 <built-in function default_int_handler>
second teardown end Ignored: 13, 25
second teardown end None: 32, 33
second teardown end 2 <built-in function default_int_handler>

The state of SIGCHLD(17) is _sighandler_noop after the first
setup_test_loop invocation, and is SIG_DFL after the second
setup_test_loop invocation.


Enrico

-- System Information:
Debian Release: buster/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 4.18.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8), LANGUAGE=en_IE:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages python3-aiohttp depends on:
ii  libc6                  2.27-6
ii  python3                3.6.6-1
ii  python3-async-timeout  3.0.0-1
ii  python3-attr           18.2.0-1
ii  python3-chardet        3.0.4-1
ii  python3-multidict      4.3.1-1+b1
ii  python3-yarl           1.2.4-1+b1

python3-aiohttp recommends no packages.

python3-aiohttp suggests no packages.

-- no debconf information
-------------- next part --------------
#!/usr/bin/env python3
import asyncio
import signal
import warnings
warnings.simplefilter('default')


def show_signals(lead):
    ignored = []
    handled = []
    none = []
    for i in range(1, signal.NSIG):
        val = signal.getsignal(i)
        if val == signal.SIG_DFL:
            continue
        elif val == signal.SIG_IGN:
            ignored.append(i)
        elif val is None:
            none.append(i)
        else:
            handled.append((i, val))
    print(lead, "Ignored:", ", ".join(str(x) for x in ignored))
    print(lead, "None:", ", ".join(str(x) for x in none))
    for num, val in handled:
        print(lead, num, val)


def setup(tag):
    show_signals(tag + " setup")

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    show_signals(tag + " after set_event_loop")
    policy = asyncio.get_event_loop_policy()
    watcher = asyncio.SafeChildWatcher()
    watcher.attach_loop(loop)
    policy.set_child_watcher(watcher)
    show_signals(tag + " after set_child_watcher")

    # cls.loop = setup_test_loop()
    loop.set_debug(True)

    show_signals(tag + " setup end")
    return loop


def teardown(tag, loop):
    closed = loop.is_closed()
    if not closed:
        loop.call_soon(loop.stop)
        loop.run_forever()
        loop.close()
    asyncio.set_event_loop(None)
    show_signals(tag + " teardown end")


loop = setup("first")
teardown("first", loop)

loop = setup("second")
teardown("second", loop)


More information about the Python-modules-team mailing list