cl / tests /test_utils.py
rottenstuff's picture
Upload 13 files
c0e2219 verified
Raw
History Blame Contribute Delete
4.55 kB
"""
Юнит-тесты для утилитарных функций colab_tunnel._utils.
"""
import sys
import subprocess
import pytest
from colab_tunnel._utils import is_ipv4, run, read_until_pattern
# is_ipv4
@pytest.mark.parametrize('addr, expected', [
('192.168.1.1', True),
('10.0.0.1', True),
('255.255.255.255', True),
('0.0.0.0', True),
('192.168.1.256', False),
('192.168.1', False),
('not-an-ip', False),
('', False),
('999.0.0.1', False),
('1.2.3.4.5', False),
])
def test_is_ipv4(addr: str, expected: bool) -> None:
assert is_ipv4(addr) is expected
# run()
def test_run_captures_output() -> None:
result = run('echo hello_world')
assert result['status_code'] == 0
assert 'hello_world' in result['output']
def test_run_nonzero_exit() -> None:
result = run('sh -c "exit 42"')
assert result['status_code'] == 42
def test_run_captures_stderr() -> None:
result = run('sh -c "echo err_msg >&2"')
assert 'err_msg' in result['output']
def test_run_timeout_returns_minus_one() -> None:
result = run('sleep 60', timeout=0.3)
assert result['status_code'] == -1
assert 'Таймаут' in result['output']
# read_until_pattern()
@pytest.mark.skipif(sys.platform == 'win32', reason='select() с пайпами не поддерживается на Windows')
def test_read_until_pattern_found_in_stdout() -> None:
process = subprocess.Popen(
[sys.executable, '-c',
'import sys, time; print("https://example.com"); sys.stdout.flush(); time.sleep(60)'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
try:
url, output = read_until_pattern(process, r'https://\S+', timeout=5.0)
assert url == 'https://example.com'
assert 'https://example.com' in output
finally:
process.kill()
process.wait()
@pytest.mark.skipif(sys.platform == 'win32', reason='select() с пайпами не поддерживается на Windows')
def test_read_until_pattern_found_in_stderr() -> None:
process = subprocess.Popen(
[sys.executable, '-c',
'import sys, time; sys.stderr.write("https://stderr.example.com\\n"); sys.stderr.flush(); time.sleep(60)'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
try:
url, _ = read_until_pattern(
process, r'https://\S+', timeout=5.0, read_from_stderr=True
)
assert 'https://stderr.example.com' in url
finally:
process.kill()
process.wait()
@pytest.mark.skipif(sys.platform == 'win32', reason='select() с пайпами не поддерживается на Windows')
def test_read_until_pattern_raises_on_timeout() -> None:
process = subprocess.Popen(
[sys.executable, '-c', 'import time; time.sleep(60)'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
try:
with pytest.raises(RuntimeError, match='URL не найден'):
read_until_pattern(process, r'https://\S+', timeout=0.5)
finally:
process.kill()
process.wait()
@pytest.mark.skipif(sys.platform == 'win32', reason='select() с пайпами не поддерживается на Windows')
def test_read_until_pattern_raises_when_process_exits_without_url() -> None:
process = subprocess.Popen(
[sys.executable, '-c', 'print("no url here at all")'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
with pytest.raises(RuntimeError):
read_until_pattern(process, r'https://\S+', timeout=5.0)
@pytest.mark.skipif(sys.platform == 'win32', reason='select() с пайпами не поддерживается на Windows')
def test_read_both_streams_finds_url_in_either() -> None:
"""URL в stderr должен находиться при read_both_streams=True."""
process = subprocess.Popen(
[sys.executable, '-c',
'import sys, time; sys.stderr.write("https://both.example.com\\n"); sys.stderr.flush(); time.sleep(60)'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
try:
url, _ = read_until_pattern(
process, r'https://\S+', timeout=5.0, read_both_streams=True
)
assert 'https://both.example.com' in url
finally:
process.kill()
process.wait()