def test_register(self): entry_1 = MocketEntry(('localhost', 80), True) entry_2 = MocketEntry(('localhost', 80), True) entry_3 = MocketEntry(('localhost', 8080), True) Mocket.register(entry_1, entry_2, entry_3) self.assertEqual(Mocket._entries, { ('localhost', 80): [entry_1, entry_2], ('localhost', 8080): [entry_3], })
def test_simple_run_with_close(monkeypatch, mocker): """Test graceful close.""" monkeypatch.setattr('os.urandom', b'\x00'.__mul__) Mocket.register( MocketEntry(('example.com', 80), [(b'HTTP/1.1 101 Switching Protocols\r\n' b'Upgrade: websocket\r\n' b'Connection: Upgrade\r\n' b'Sec-WebSocket-Accept: icx+yqv66kxgm0fcwalwlflwtai=\r\n' b'\r\n' b'\x81\x81\x00\x00\x00\x00A\x88\x80\xba51e')])) session = WebsocketSession(WebSocket('ws://example.com/')) session._selector_cls = FakeSelector session._on_ready() session._regular_orig = session._regular mocker.patch('lomond.websocket.WebSocket._send_close') mocker.patch.object(session.websocket, 'send_ping') session.websocket.state.session = session _events = list(session.run()) assert len(_events) == 7 assert isinstance(_events[0], events.Connecting) assert isinstance(_events[1], events.Connected) assert isinstance(_events[2], events.Ready) assert isinstance(_events[3], events.Poll) assert isinstance(_events[4], events.Text) assert isinstance(_events[5], events.Closing) assert isinstance(_events[6], events.Disconnected) assert _events[6].graceful
def test_unresponsive(monkeypatch, mocker): """Check ping timeout.""" monkeypatch.setattr( 'os.urandom', b'\x00'.__mul__ ) Mocket.register( MocketEntry( ('example.com', 80), [( b'HTTP/1.1 101 Switching Protocols\r\n' b'Upgrade: websocket\r\n' b'Connection: Upgrade\r\n' b'Sec-WebSocket-Accept: icx+yqv66kxgm0fcwalwlflwtai=\r\n' b'\r\n' b'\x81\x81\x00\x00\x00\x00A' )] ) ) # mocket doesn't support .pending() call which is used when ssl is used session = WebsocketSession(WebSocket('ws://example.com/')) session._selector_cls = FakeSelector session._on_ready() # well, we have to cheat a little. The thing is, inner loop of # run() sets last poll time to time.time and so we would have to # wait for some time to actually hit poll / ping. This is not desirable # so we can do the following: # save original _regular call into _regular_orig # (_regular is a first - well, technically, a second) call inside run # after _poll_start is set which makes it a nice candidate for monkey-patch # location. Here's how we do it: session._regular_orig = session._regular mocker.patch( 'lomond.websocket.WebSocket._send_close') mocker.patch.object(session.websocket, 'send_ping') _events = [] iter_events = iter(session.run(ping_timeout=5)) for event in iter_events: _events.append(event) if event.name == 'text': break with freeze_time("1994-05-01 18:41:00"): for event in iter_events: _events.append(event) assert len(_events) == 8 assert isinstance(_events[0], events.Connecting) assert isinstance(_events[1], events.Connected) assert isinstance(_events[2], events.Ready) assert isinstance(_events[3], events.Poll) assert isinstance(_events[4], events.Text) assert isinstance(_events[5], events.Poll) assert isinstance(_events[6], events.Unresponsive) assert isinstance(_events[7], events.Disconnected)
def test_socket_fail(session, mocker): def select_that_throws_exception(*args, **kwargs): raise select.error('this is just a test') Mocket.register(MocketEntry(('example.com', 80), [b'some binary data'])) mocker.patch('lomond.session.select.select', select_that_throws_exception) with pytest.raises(WebsocketSession._SocketFail): session._select(session._sock, poll=5)
def test_socket_as_context_manager(self): addr = ("localhost", 80) Mocket.register(MocketEntry(addr, ["Show me.\r\n"])) with Mocketizer(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as _so: _so.connect(addr) _so.sendall(encode_to_bytes("Whatever...")) data = _so.recv(4096) self.assertEqual(data, encode_to_bytes("Show me.\r\n"))
def test_connect(session, mocker): Mocket.register( MocketEntry( ('example.com', 80), [b'some binary data'] ) ) _socket, _proxy = session._connect() assert isinstance(_socket, socket.socket)
def test_makefile(self): addr = ("localhost", 80) Mocket.register(MocketEntry(addr, ["Show me.\r\n"])) with Mocketizer(): _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(addr) fp = _so.makefile("rb") _so.sendall(encode_to_bytes("...\r\n")) self.assertEqual(fp.read().strip(), encode_to_bytes("Show me.")) self.assertEqual(len(Mocket.request_list()), 1)
def test_send_command(self): Mocket.register( MocketEntry(self.bulb_addr, [b'{"id":1, "result":["ok"]}\r\n'])) with Bulb(*self.bulb_addr, **self.kwargs | { "id": 1, "support": ["set_ct_abx"] }) as b: loop = asyncio.get_event_loop() loop.run_until_complete( b.send_command("set_ct_abx", [3500, "smooth", 500]))
def test_subsequent_recv_requests_have_correct_length(self): Mocket.register( MocketEntry(('localhost', 80), [b'Long payload', b'Short'])) _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(('localhost', 80)) _so.sendall(b'first\r\n') assert _so.recv(4096) == b'Long payload' _so.sendall(b'second\r\n') assert _so.recv(4096) == b'Short' _so.close()
def session_with_socket(monkeypatch): Mocket.register( MocketEntry( ('example.com', 80), [b'some binary data'] ) ) session_obj = session(monkeypatch) return session_obj
def test_subsequent_recv_requests_have_correct_length(self): addr = ("localhost", 80) Mocket.register(MocketEntry(addr, [b"Long payload", b"Short"])) with Mocketizer(): _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(addr) _so.sendall(b"first\r\n") self.assertEqual(_so.recv(4096), b"Long payload") _so.sendall(b"second\r\n") self.assertEqual(_so.recv(4096), b"Short") _so.close()
def test_collect_last_request(self): addr = ("localhost", 80) entry = MocketEntry(addr, True) Mocket.register(entry) with Mocketizer(): _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(addr) _so.sendall(b"data\r\n") _so.close() self.assertEqual(Mocket.last_request(), b"data\r\n")
def register_conversation(self, response_port=None, response_data=None): from mocket import Mocket, MocketEntry response_port = response_port or self.LORA_RESPONSE_PORT response_data = response_data or [] lora_entry = MocketEntry(location=(None, None), responses=response_data) lora_entry.request_cls = bytearray Mocket.reset() Mocket.register(lora_entry) def recvfrom(self, buffersize): if response_data: buffer = self.recv(buffersize) return buffer, response_port else: return None, response_port self.monkeypatch.setattr(MocketSocket, 'recvfrom', recvfrom, raising=False)
def test_recv_into(self): addr = ("localhost", 80) Mocket.register(MocketEntry(addr, [b"Long payload", b"Short"])) buffer = io.BytesIO() with Mocketizer(): _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(addr) _so.sendall(b"first\r\n") self.assertEqual(_so.recv_into(buffer, 4096), 12) _so.sendall(b"second\r\n") self.assertEqual(_so.recv_into(buffer), 5) _so.close() buffer.seek(0) assert buffer.read() == b"Long payloadShort"
def test_recv_into(self): Mocket.register( MocketEntry(('localhost', 80), [b'Long payload', b'Short'])) buffer = io.BytesIO() with Mocketizer(): _so = socket.socket(socket.AF_INET, socket.SOCK_STREAM) _so.connect(('localhost', 80)) _so.sendall(b'first\r\n') assert _so.recv_into(buffer, 4096) == 12 _so.sendall(b'second\r\n') assert _so.recv_into(buffer) == 5 _so.close() buffer.seek(0) assert buffer.read() == b'Long payloadShort'
def test_simple_run(monkeypatch, mocker): monkeypatch.setattr('os.urandom', b'\x00'.__mul__) Mocket.register( MocketEntry(('example.com', 80), [(b'HTTP/1.1 101 Switching Protocols\r\n' b'Upgrade: websocket\r\n' b'Connection: Upgrade\r\n' b'Sec-WebSocket-Accept: icx+yqv66kxgm0fcwalwlflwtai=\r\n' b'\r\n' b'\x81\x81\x00\x00\x00\x00A')])) # mocket doesn't support .pending() call which is used when ssl is used session = WebsocketSession(WebSocket('ws://example.com/')) session._on_ready() # well, we have to cheat a little. The thing is, inner loop of # run() sets last poll time to time.time and so we would have to # wait for some time to actually hit poll / ping. This is not desirable # so we can do the following: # save original _regular call into _regular_orig # (_regular is a first - well, technically, a second) call inside run # after _poll_start is set which makes it a nice candidate for monkey-patch # location. Here's how we do it: session._regular_orig = session._regular mocker.patch('lomond.websocket.WebSocket._send_close') mocker.patch.object(session.websocket, 'send_ping') mocker.patch('lomond.session.WebsocketSession._select', lambda self, sock, poll: [True, False]) _events = list(session.run()) assert len(_events) == 6 assert isinstance(_events[0], events.Connecting) assert isinstance(_events[1], events.Connected) assert isinstance(_events[2], events.Ready) assert isinstance(_events[3], events.Poll) assert isinstance(_events[4], events.Text) assert isinstance(_events[5], events.Disconnected)
def test_empty_getresponse(self): entry = MocketEntry(('localhost', 8080), []) self.assertEqual(entry.get_response(), encode_to_bytes(''))
def test_getresponse(self): entry = MocketEntry(('localhost', 8080), ['Show me.\r\n']) self.assertEqual(entry.get_response(), encode_to_bytes('Show me.\r\n'))
def test_getentry(self): entry = MocketEntry(('localhost', 80), True) Mocket.register(entry) self.assertEqual(Mocket.get_entry('localhost', 80, True), entry)
def test_getresponse(self): entry = MocketEntry(("localhost", 8080), ["Show me.\r\n"]) self.assertEqual(entry.get_response(), encode_to_bytes("Show me.\r\n"))
def test_raise_exception(self): entry = MocketEntry(("localhost", 8080), [IOError()]) with self.assertRaises(IOError): entry.get_response()