diff options
author | Andy McCurdy <andy@andymccurdy.com> | 2019-05-26 16:26:32 -0700 |
---|---|---|
committer | Andy McCurdy <andy@andymccurdy.com> | 2019-05-26 16:26:32 -0700 |
commit | e6eff96a2da8ff187910747831de8785a191b5ab (patch) | |
tree | aa2c7afd2c1e7b94af2ce52f2df6959de5e7e79a | |
parent | 6b98c72ad9ca33befbe0e9d7f2d47623981ebed3 (diff) | |
download | redis-py-e6eff96a2da8ff187910747831de8785a191b5ab.tar.gz |
monitor command now has full command text. test suite improved
-rwxr-xr-x | redis/client.py | 12 | ||||
-rw-r--r-- | tests/test_monitor.py | 37 |
2 files changed, 41 insertions, 8 deletions
diff --git a/redis/client.py b/redis/client.py index 0b9863f..f024142 100755 --- a/redis/client.py +++ b/redis/client.py @@ -2934,6 +2934,9 @@ class Monitor(object): next_command() method returns one command from monitor listen() method yields commands from monitor. """ + monitor_re = re.compile(r'\[(\d+) (.+):(\d+)\] (.*)') + command_re = re.compile(r'"(.*?)(?<!\\)"') + def __init__(self, connection_pool): self.connection_pool = connection_pool self.connection = self.connection_pool.get_connection('MONITOR') @@ -2956,12 +2959,13 @@ class Monitor(object): if isinstance(response, bytes): response = self.connection.encoder.decode(response, force=True) command_time, command_data = response.split(' ', 1) - m = re.match(r'\[(\d+) (.+):(\d+)\] (.*)', command_data) + m = self.monitor_re.match(command_data) db_id, client_address, client_port, command = m.groups() - command = re.match(r'"(\w*)"+', command).groups() + command = ' '.join(self.command_re.findall(command)) + command = command.replace('\\"', '"') return { 'time': float(command_time), - 'db': db_id, + 'db': int(db_id), 'client_address': client_address, 'client_port': client_port, 'command': command @@ -2969,7 +2973,7 @@ class Monitor(object): def listen(self): "Listen for commands coming to the server." - while 1: + while True: yield self.next_command() diff --git a/tests/test_monitor.py b/tests/test_monitor.py index da0c992..831f9d1 100644 --- a/tests/test_monitor.py +++ b/tests/test_monitor.py @@ -1,10 +1,39 @@ from __future__ import unicode_literals +def wait_for_command(client, monitor, command): + # issue a command with a key name that's local to this process. + # if we find a command with our key before the command we're waiting + # for, something went wrong + key = '__REDIS-PY-%s__' % str(client.client_id()) + client.get(key) + while True: + monitor_response = monitor.next_command() + if command in monitor_response['command']: + return monitor_response + if key in monitor_response['command']: + return None + + class TestPipeline(object): - def test_monitor(self, r): + def test_response_pieces(self, r): with r.monitor() as m: r.ping() - response = m.next_command() - assert set(response.keys()) == {'time', 'db', 'client_address', - 'client_port', 'command'} + response = wait_for_command(r, m, 'PING') + assert isinstance(response['time'], float) + assert response['db'] == 9 + assert isinstance(response['client_address'], str) + assert isinstance(response['client_port'], str) + assert response['command'] == 'PING' + + def test_command_with_quoted_key(self, r): + with r.monitor() as m: + r.get('foo"bar') + response = wait_for_command(r, m, 'GET foo"bar') + assert response['command'] == 'GET foo"bar' + + def test_wait_command_not_found(self, r): + "Make sure the wait_for_command func works when command is not found" + with r.monitor() as m: + response = wait_for_command(r, m, 'nothing') + assert response is None |