blob: 0925d847a9ebf37c3b17f038b35414b444400991 [file] [log] [blame]
Adam Israeldcdf82b2017-08-15 15:26:43 -04001import asyncio
2import json
Adam Israeldcdf82b2017-08-15 15:26:43 -04003from collections import deque
4
Adam Israelc3e6c2e2018-03-01 09:31:50 -05005import mock
6from juju.client.connection import Connection
Adam Israeldcdf82b2017-08-15 15:26:43 -04007from websockets.exceptions import ConnectionClosed
8
Adam Israelc3e6c2e2018-03-01 09:31:50 -05009import pytest
10
Adam Israeldcdf82b2017-08-15 15:26:43 -040011from .. import base
Adam Israeldcdf82b2017-08-15 15:26:43 -040012
13
14class WebsocketMock:
15 def __init__(self, responses):
16 super().__init__()
17 self.responses = deque(responses)
18 self.open = True
19
20 async def send(self, message):
21 pass
22
23 async def recv(self):
24 if not self.responses:
25 await asyncio.sleep(1) # delay to give test time to finish
26 raise ConnectionClosed(0, 'ran out of responses')
27 return json.dumps(self.responses.popleft())
28
29 async def close(self):
30 self.open = False
31
32
33@pytest.mark.asyncio
34async def test_out_of_order(event_loop):
Adam Israeldcdf82b2017-08-15 15:26:43 -040035 ws = WebsocketMock([
36 {'request-id': 1},
37 {'request-id': 3},
38 {'request-id': 2},
39 ])
40 expected_responses = [
41 {'request-id': 1},
42 {'request-id': 2},
43 {'request-id': 3},
44 ]
Adam Israelc3e6c2e2018-03-01 09:31:50 -050045 minimal_facades = [{'name': 'Pinger', 'versions': [1]}]
46 con = None
Adam Israeldcdf82b2017-08-15 15:26:43 -040047 try:
Adam Israelc3e6c2e2018-03-01 09:31:50 -050048 with \
49 mock.patch('websockets.connect', base.AsyncMock(return_value=ws)), \
50 mock.patch(
51 'juju.client.connection.Connection.login',
52 base.AsyncMock(return_value={'response': {
53 'facades': minimal_facades,
54 }}),
55 ), \
56 mock.patch('juju.client.connection.Connection._get_ssl'), \
57 mock.patch('juju.client.connection.Connection._pinger', base.AsyncMock()):
58 con = await Connection.connect('0.1.2.3:999')
Adam Israeldcdf82b2017-08-15 15:26:43 -040059 actual_responses = []
60 for i in range(3):
61 actual_responses.append(await con.rpc({'version': 1}))
62 assert actual_responses == expected_responses
63 finally:
Adam Israelc3e6c2e2018-03-01 09:31:50 -050064 if con:
65 await con.close()