-
-
Notifications
You must be signed in to change notification settings - Fork 67
Fix empty ValueError in FakeTcpServer #440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Fix empty ValueError in FakeTcpServer #440
Conversation
558daf2 to
9c02863
Compare
cunla
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you write tests for this?
Done. @cunla can you please re-review? |
71c1906 to
00f1d23
Compare
|
I am not sure whether this is needed anymore. Check out https://github.com/cunla/fakeredis-py/pull/441/files |
@cunla While you removed the Traceback (most recent call last):
...
File ".../fakeredis-py/fakeredis/_tcp_server.py", line 126, in handle
self.writer.dump(e)
File ".../fakeredis-py/fakeredis/_tcp_server.py", line 82, in dump
self.write(f"-{prefix} {value.args[0]}\r\n".encode())
~~~~~~~~~~^^^
IndexError: tuple index out of rangeThis is reproducible using the latest changes from your PR with the following reproducer import socket
import time
from contextlib import closing, contextmanager
from threading import Thread
import redis
from fakeredis import TcpFakeServer
@contextmanager
def redis_server():
host = "127.0.0.1"
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind(("", 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
port = s.getsockname()[1]
class TcpFakeServerWithExceptions(TcpFakeServer):
def handle_error(self, request, client_address):
super().handle_error(request, client_address)
# Send an error message back to the client here
request.sendall(b"An error occurred on the server.")
server_address = (host, port)
server = TcpFakeServerWithExceptions(server_address)
thread = Thread(target=server.serve_forever, daemon=True)
thread.start()
time.sleep(0.1)
try:
with redis.Redis(host=host, port=port) as r:
yield r
finally:
server.server_close()
server.shutdown()
thread.join()
def test_bulk_string_length(redis_server):
"""Test that malformed bulk string input is handled correctly."""
host = redis_server.connection_pool.connection_kwargs.get("host")
port = redis_server.connection_pool.connection_kwargs.get("port")
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.connect((host, port))
s.sendall(b"$ 1\ntest")
data = s.recv(1024).decode()
assert data != "An error occurred on the server.", data
if __name__ == "__main__":
with redis_server() as r:
test_bulk_string_length(r) |
|
The exception appears to originate here Traceback (most recent call last):
File ".../fakeredis-py/fakeredis/_tcp_server.py", line 123, in handle
self.current_client.get_socket().sendall(data)
File ".../fakeredis-py/fakeredis/_basefakesocket.py", line 360, in sendall
self._parser.send(data)
File ".../fakeredis-py/fakeredis/_basefakesocket.py", line 207, in _parse_commands
line, buf = self._extract_line(buf)
^^^^^^^^^^^^^^^^^^^^^^^
File ".../fakeredis-py/fakeredis/_basefakesocket.py", line 194, in _extract_line
assert line.endswith(b"\r\n")
^^^^^^^^^^^^^^^^^^^^^^
AssertionErrorThe fix being to just add an exception message here. Though, one further comment. Checks like these really should be made into proper exceptions instead of using |
The fact that the the FakeTcpServer is raising an empty
ValueErroris causing unexpected errors herefakeredis-py/fakeredis/_tcp_server.py
Lines 101 to 103 in 49c46f7
This is easily fixed by adding proper error messages to the
ValueError