summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy McCurdy <andy@andymccurdy.com>2019-05-26 16:26:32 -0700
committerAndy McCurdy <andy@andymccurdy.com>2019-05-26 16:26:32 -0700
commite6eff96a2da8ff187910747831de8785a191b5ab (patch)
treeaa2c7afd2c1e7b94af2ce52f2df6959de5e7e79a
parent6b98c72ad9ca33befbe0e9d7f2d47623981ebed3 (diff)
downloadredis-py-e6eff96a2da8ff187910747831de8785a191b5ab.tar.gz
monitor command now has full command text. test suite improved
-rwxr-xr-xredis/client.py12
-rw-r--r--tests/test_monitor.py37
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