mirror of
https://github.com/romanz/amodem.git
synced 2026-04-20 04:56:25 +08:00
stream: use async I/O to avoid real-time problems.
This commit is contained in:
70
tests/test_async.py
Normal file
70
tests/test_async.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import mock
|
||||
import time
|
||||
import pytest
|
||||
from amodem import async
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format='%(message)s')
|
||||
|
||||
|
||||
def test_async_reader():
|
||||
def _read(n):
|
||||
time.sleep(n * 0.1)
|
||||
return b'\x00' * n
|
||||
s = mock.Mock()
|
||||
s.read = _read
|
||||
r = async.AsyncReader(s, 1)
|
||||
|
||||
n = 5
|
||||
assert r.read(n) == b'\x00' * n
|
||||
r.close()
|
||||
assert r.stream is None
|
||||
r.close()
|
||||
|
||||
|
||||
def test_async_write():
|
||||
result = []
|
||||
|
||||
def _write(buf):
|
||||
time.sleep(len(buf) * 0.1)
|
||||
result.append(buf)
|
||||
s = mock.Mock()
|
||||
s.write = _write
|
||||
w = async.AsyncWriter(s)
|
||||
|
||||
w.write('foo')
|
||||
w.write(' ')
|
||||
w.write('bar')
|
||||
w.close()
|
||||
assert w.stream is None
|
||||
w.close()
|
||||
assert result == ['foo', ' ', 'bar']
|
||||
|
||||
|
||||
def test_async_reader_error():
|
||||
s = mock.Mock()
|
||||
s.read.side_effect = IOError()
|
||||
r = async.AsyncReader(s, 1)
|
||||
with pytest.raises(IOError):
|
||||
r.read(3)
|
||||
|
||||
|
||||
def test_async_writer_error():
|
||||
s = mock.Mock()
|
||||
s.write.side_effect = IOError()
|
||||
w = async.AsyncWriter(s)
|
||||
w.write('123')
|
||||
w.thread.join()
|
||||
with pytest.raises(IOError):
|
||||
w.write('456')
|
||||
assert s.write.mock_calls == [mock.call('123')]
|
||||
|
||||
|
||||
def test_underflow():
|
||||
s = mock.Mock()
|
||||
w = async.AsyncWriter(s)
|
||||
w.write('blah')
|
||||
w.thread.join()
|
||||
assert s.write.mock_calls == [mock.call('blah')]
|
||||
with pytest.raises(IOError):
|
||||
w.write('xyzw')
|
||||
@@ -9,6 +9,7 @@ from amodem import common
|
||||
from amodem import dsp
|
||||
from amodem import sampling
|
||||
from amodem import config
|
||||
from amodem import async
|
||||
config = config.fastest()
|
||||
|
||||
import logging
|
||||
@@ -26,7 +27,7 @@ class Args(object):
|
||||
return None
|
||||
|
||||
|
||||
def run(size, chan=None, df=0, success=True):
|
||||
def run(size, chan=None, df=0, success=True, reader=None):
|
||||
tx_data = os.urandom(size)
|
||||
tx_audio = BytesIO()
|
||||
send.main(config=config, src=BytesIO(tx_data), dst=tx_audio)
|
||||
@@ -42,13 +43,19 @@ def run(size, chan=None, df=0, success=True):
|
||||
|
||||
data = common.dumps(data)
|
||||
rx_audio = BytesIO(data)
|
||||
|
||||
rx_data = BytesIO()
|
||||
d = BytesIO()
|
||||
result = recv.main(config=config, src=rx_audio, dst=rx_data,
|
||||
dump_audio=d)
|
||||
dump = BytesIO()
|
||||
|
||||
if reader:
|
||||
rx_audio = reader(rx_audio)
|
||||
try:
|
||||
result = recv.main(config=config, src=rx_audio, dst=rx_data,
|
||||
dump_audio=dump)
|
||||
finally:
|
||||
rx_audio.close()
|
||||
|
||||
rx_data = rx_data.getvalue()
|
||||
assert data.startswith(d.getvalue())
|
||||
assert data.startswith(dump.getvalue())
|
||||
|
||||
assert result == success
|
||||
if success:
|
||||
@@ -64,6 +71,11 @@ def test_small(small_size):
|
||||
run(small_size, chan=lambda x: x)
|
||||
|
||||
|
||||
def test_async():
|
||||
run(1024, chan=lambda x: x,
|
||||
reader=lambda s: async.AsyncReader(s, 128))
|
||||
|
||||
|
||||
def test_error():
|
||||
skip = 32000 # remove trailing silence
|
||||
run(1024, chan=lambda x: x[:-skip], success=False)
|
||||
|
||||
Reference in New Issue
Block a user