Skip to content

Commit 64eef0f

Browse files
committed
asyncio: add to test suite
This does not cover the full mpd.asyncio functionality yet, but large enough parts to show when mpd.asyncio falls apart completely.
1 parent 06b3a59 commit 64eef0f

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

mpd/tests.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929
"(twisted is not available for python >= 3.0 && python < 3.3)")
3030
TWISTED_MISSING = True
3131

32+
if sys.version_info >= (3, 5):
33+
# asyncio would be available in 3.4, but it's not supported by mpd.asyncio
34+
import asyncio
35+
else:
36+
asyncio = None
37+
3238
try:
3339
import mock
3440
except ImportError:
@@ -905,6 +911,125 @@ def success(result):
905911

906912
self.protocol.close().addCallback(success)
907913

914+
class AsyncMockServer:
915+
def __init__(self):
916+
self._output = asyncio.Queue()
917+
self._expectations = []
918+
919+
def get_streams(self):
920+
result = asyncio.Future()
921+
result.set_result((self, self))
922+
return result
923+
924+
def readline(self):
925+
# directly passing around the awaitable
926+
return self._output.get()
927+
928+
def write(self, data):
929+
try:
930+
next_write = self._expectations[0][0][0]
931+
except IndexError:
932+
self.error("Data written to mock even though none expected: %r" % data)
933+
if next_write == data:
934+
self._expectations[0][0].pop(0)
935+
self._feed()
936+
else:
937+
self.error("Mock got %r, expected %r" % (data, next_write))
938+
939+
def error(self, message):
940+
raise AssertionError(message)
941+
942+
def _feed(self):
943+
if len(self._expectations[0][0]) == 0:
944+
_, response_lines = self._expectations.pop(0)
945+
for l in response_lines:
946+
self._output.put_nowait(l)
947+
948+
def expect_exchange(self, request_lines, response_lines):
949+
self._expectations.append((request_lines, response_lines))
950+
self._feed()
951+
952+
@unittest.skipIf(asyncio is None, "requires asyncio to be available")
953+
class TestAsyncioMPD(unittest.TestCase):
954+
def init_client(self, odd_hello=None):
955+
import mpd.asyncio
956+
957+
self.loop = asyncio.get_event_loop()
958+
959+
self.mockserver = AsyncMockServer()
960+
asyncio.open_connection = mock.MagicMock(return_value=self.mockserver.get_streams())
961+
962+
if odd_hello is None:
963+
hello_lines = [b'OK MPD mocker\n']
964+
else:
965+
hello_lines = odd_hello
966+
967+
self.mockserver.expect_exchange([], hello_lines)
968+
969+
self.client = mpd.asyncio.MPDClient()
970+
self._await(self.client.connect(TEST_MPD_HOST, TEST_MPD_PORT, loop=self.loop))
971+
972+
asyncio.open_connection.assert_called_with(TEST_MPD_HOST, TEST_MPD_PORT, loop=self.loop)
973+
974+
def _await(self, future):
975+
return self.loop.run_until_complete(future)
976+
977+
def test_oddhello(self):
978+
self.assertRaises(mpd.base.ProtocolError, self.init_client, odd_hello=[b'NOT OK\n'])
979+
980+
@unittest.skip("This test would add 5 seconds of idling to the run")
981+
def test_noresponse(self):
982+
self.assertRaises(mpd.base.ConnectionError, self.init_client, odd_hello=[])
983+
984+
def test_status(self):
985+
self.init_client()
986+
987+
self.mockserver.expect_exchange([b"status\n"], [
988+
b"volume: 70\n",
989+
b"repeat: 0\n",
990+
b"random: 1\n",
991+
b"single: 0\n",
992+
b"consume: 0\n",
993+
b"playlist: 416\n",
994+
b"playlistlength: 7\n",
995+
b"mixrampdb: 0.000000\n",
996+
b"state: play\n",
997+
b"song: 4\n",
998+
b"songid: 19\n",
999+
b"time: 28:403\n",
1000+
b"elapsed: 28.003\n",
1001+
b"bitrate: 465\n",
1002+
b"duration: 403.066\n",
1003+
b"audio: 44100:16:2\n",
1004+
b"OK\n",
1005+
])
1006+
1007+
status = self._await(self.client.status())
1008+
self.assertEqual(status, {
1009+
'audio': '44100:16:2',
1010+
'bitrate': '465',
1011+
'consume': '0',
1012+
'duration': '403.066',
1013+
'elapsed': '28.003',
1014+
'mixrampdb': '0.000000',
1015+
'playlist': '416',
1016+
'playlistlength': '7',
1017+
'random': '1',
1018+
'repeat': '0',
1019+
'single': '0',
1020+
'song': '4',
1021+
'songid': '19',
1022+
'state': 'play',
1023+
'time': '28:403',
1024+
'volume': '70',
1025+
})
1026+
1027+
def test_mocker(self):
1028+
"""Does the mock server refuse unexpected writes?"""
1029+
self.init_client()
1030+
1031+
self.mockserver.expect_exchange([b"expecting odd things\n"], [b""])
1032+
self.assertRaises(AssertionError, self._await, self.client.status())
9081033

9091034
if __name__ == '__main__':
9101035
unittest.main()

0 commit comments

Comments
 (0)