async def test_process_stopped_on_stop(process_queue): component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 0, 'revive': False, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001}) p = await process_queue.get() assert p.returncode is None component.stop() await asyncio.wait_for(p.wait(), 1) await component.async_close()
async def test_hard_terminate_process(short_start_delay, short_sigint_timeout, process_queue, tmpdir): component_path = tmpdir / 'component.py' running_path = tmpdir / 'running' signum = 'signal.SIGBREAK' if sys.platform == 'win32' else 'signal.SIGINT' with open(component_path, 'w', encoding='utf-8') as f: f.write('import signal, sys, time\n' f'signal.signal({signum}, lambda *args: None)\n' f'open(r"{running_path}", "w").close()\n' 'while True:\n' ' time.sleep(0.001)\n') component = Component({ 'name': 'name', 'args': ['python', str(component_path)], 'delay': 0, 'revive': False }) while not running_path.exists(): await asyncio.sleep(0.001) p = await process_queue.get() assert p.returncode is None await component.async_close() assert p.returncode is not None
async def test_revive_on_delay(): component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 1, 'revive': False, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001}) for revive in [True, False] * 5: component.set_revive(revive) assert component.revive == revive assert component.status == Status.DELAYED await asyncio.sleep(0) await component.async_close() assert component.status == Status.STOPPED
async def test_closed(): component = Component({ 'name': 'name', 'args': ['sleep', '10'], 'delay': 0, 'revive': False }) assert not component.closed.done() await component.async_close() assert component.closed.done()
async def test_initial_status(): component = Component({ 'name': 'name', 'args': ['sleep', '10'], 'delay': 1, 'revive': False }) assert component.status == Status.DELAYED await component.async_close() assert component.status == Status.STOPPED component = Component({ 'name': 'name', 'args': ['sleep', '10'], 'delay': 0, 'revive': False }) assert component.status == Status.STOPPED await component.async_close() assert component.status == Status.STOPPED
async def test_process_stopped_on_close(short_start_delay, process_queue): component = Component({ 'name': 'name', 'args': ['sleep', '10'], 'delay': 0, 'revive': False }) p = await process_queue.get() await asyncio.sleep(0.01) assert p.returncode is None await component.async_close() assert p.returncode is not None
async def test_call_create_subprocess_exec_with_revive(short_start_delay): with unittest.mock.patch('asyncio.create_subprocess_exec') as create: create.return_value.stdout.readline.return_value = None component = Component({ 'name': 'name', 'args': ['sleep', '0'], 'delay': 0, 'revive': True }) while create.call_count <= 5: await asyncio.sleep(0.001) await component.async_close()
async def test_conf_properties(): conf = { 'name': 'name', 'args': ['sleep', '10'], 'delay': 0, 'revive': False } component = Component(conf) assert component.name == conf['name'] assert component.args == conf['args'] assert component.delay == conf['delay'] assert component.revive == conf['revive'] await component.async_close()
async def test_closed(): component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 0, 'revive': False, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001}) assert not component.is_closed await component.async_close() assert component.is_closed
async def test_initial_status(): component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 1, 'revive': False, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001}) assert component.status == Status.DELAYED await component.async_close() assert component.status == Status.STOPPED component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 0, 'revive': False}) assert component.status == Status.STOPPED await component.async_close() assert component.status == Status.STOPPED
async def test_revive_on_delay(): component = Component({ 'name': 'name', 'args': ['sleep', '10'], 'delay': 1, 'revive': False }) for revive in [True, False] * 5: component.set_revive(revive) assert component.revive == revive assert component.status == Status.DELAYED await asyncio.sleep(0) await component.async_close() assert component.status == Status.STOPPED
async def test_conf_properties(): conf = {'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(10)'], 'delay': 0, 'revive': False, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001} component = Component(conf) assert component.name == conf['name'] assert component.delay == conf['delay'] assert component.revive == conf['revive'] await component.async_close()
async def test_call_create_subprocess_exec_with_revive(): with unittest.mock.patch('asyncio.create_subprocess_exec') as create: create.return_value.stdout.readline.return_value = None component = Component({ 'name': 'name', 'args': [sys.executable, '-c', 'import time; time.sleep(0)'], 'delay': 0, 'revive': True, 'start_delay': 0.001, 'create_timeout': 0.1, 'sigint_timeout': 0.001, 'sigkill_timeout': 0.001}) while create.call_count <= 5: await asyncio.sleep(0.001) await component.async_close()
def create_component_with_status_queue(conf): component = Component(conf) status_queue = aio.Queue() component.register_change_cb( lambda: status_queue.put_nowait(component.status)) return component, status_queue