Skip to content
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

redis 3.3.0 returns different values than expected causing failing tests in test_fakeredis.py #242

Closed
isms opened this issue Jul 29, 2019 · 3 comments

Comments

@isms
Copy link
Contributor

isms commented Jul 29, 2019

Excluding health check failures covered by #240, there are still this unexpected results:

======================================================================
FAIL: test_ping (__main__.TestFakeStrictRedis)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 2963, in test_ping
    self.assertEqual(self.redis.execute_command('ping', 'test'), b'test')
AssertionError: False != b'test'

======================================================================
FAIL: test_zadd_minus_zero (__main__.TestFakeStrictRedis)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 1786, in test_zadd_minus_zero
    self.assertEqual(self.redis.execute_command('zscore', 'foo', 'a'), b'-0')
AssertionError: -0.0 != b'-0'

======================================================================
FAIL: test_ping (__main__.TestFakeStrictRedisDecodeResponses)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 2963, in test_ping
    self.assertEqual(self.redis.execute_command('ping', 'test'), b'test')
  File "test_fakeredis.py", line 4271, in assertEqual
    super(DecodeMixin, self).assertEqual(a, self._decode(b), msg)
AssertionError: False != 'test'

======================================================================
FAIL: test_zadd_minus_zero (__main__.TestFakeStrictRedisDecodeResponses)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 1786, in test_zadd_minus_zero
    self.assertEqual(self.redis.execute_command('zscore', 'foo', 'a'), b'-0')
  File "test_fakeredis.py", line 4271, in assertEqual
    super(DecodeMixin, self).assertEqual(a, self._decode(b), msg)
AssertionError: -0.0 != '-0'

======================================================================
FAIL: test_ping (__main__.TestRealStrictRedis)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 2963, in test_ping
    self.assertEqual(self.redis.execute_command('ping', 'test'), b'test')
AssertionError: False != b'test'

======================================================================
FAIL: test_zadd_minus_zero (__main__.TestRealStrictRedis)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 1786, in test_zadd_minus_zero
    self.assertEqual(self.redis.execute_command('zscore', 'foo', 'a'), b'-0')
AssertionError: -0.0 != b'-0'

======================================================================
FAIL: test_ping (__main__.TestRealStrictRedisDecodeResponses)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 2963, in test_ping
    self.assertEqual(self.redis.execute_command('ping', 'test'), b'test')
  File "test_fakeredis.py", line 4271, in assertEqual
    super(DecodeMixin, self).assertEqual(a, self._decode(b), msg)
AssertionError: False != 'test'

======================================================================
FAIL: test_zadd_minus_zero (__main__.TestRealStrictRedisDecodeResponses)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fakeredis.py", line 1786, in test_zadd_minus_zero
    self.assertEqual(self.redis.execute_command('zscore', 'foo', 'a'), b'-0')
  File "test_fakeredis.py", line 4271, in assertEqual
    super(DecodeMixin, self).assertEqual(a, self._decode(b), msg)
AssertionError: -0.0 != '-0'

----------------------------------------------------------------------
@Raab70
Copy link
Contributor

Raab70 commented Jul 30, 2019

I think this is really two failures and I can confirm that these are both legitimate (albeit possibly not purposeful) redis-py API changes:

Running redis==3.3.2

>>> from redis import StrictRedis
>>> rc = StrictRedis()
>>> rc.execute_command('ping', 'test')
False
>>> rc.zadd('foo', {'a': -0.0})
1
>>> rc.zadd('foo', {'a': 0.0})
0
>>> rc.execute_command('zscore', 'foo', 'a')
-0.0

Running redis==3.2.1

>>> from redis import StrictRedis
>>> rc = StrictRedis()
>>> rc.execute_command('ping', 'test')
b'test'
>>> rc.zadd('foobarbaz', {'a': -0.0})
1
>>> rc.zadd('foobarbaz', {'a': 0.0})
0
>>> rc.execute_command('zscore', 'foobarbaz', 'a')
b'-0'

Neither of which is called out in the changelog: https://github.com/andymccurdy/redis-py/blob/master/CHANGES

Should we open issues in redis-py?

@bmerry
Copy link
Collaborator

bmerry commented Jul 31, 2019

I think it is most likely this issue from the changelog:

Response callbacks are now case insensitive. This allows users that
call Redis.execute_command() directly to pass lower-case command
names and still get reasonable responses. #1168

So I think the short-term fix is to change the fakeredis tests to pass the command name in uppercase and to expect the redis 3.3+ behaviour (which should also be the 3.2- behaviour for uppercase command names).

Unfortunately this will probably weaken some of the tests because they're ensuring that the raw value (prior to the conversions done by redis-py) exactly matches real redis e.g. the sign of zero returned by zscore. That may prove important if anyone ever extends fakeredis to support other redis frontends like aioredis.

@Raab70
Copy link
Contributor

Raab70 commented Jul 31, 2019

@bmerry I was thinking that would be the issue as well but it seems not. The changelog does indicate a change in support for lowercase commands but it reads as though it is expanding support for lowercase commands. I can confirm that the case doesn't matter using redis==3.3.2:

>>> from redis import StrictRedis
>>> rc = StrictRedis()
>>> rc.execute_command("PING", "test")
False
>>> rc.ping()
True
>>> rc.execute_command("PING")
True

It certainly seems like they may have inadvertently removed support for the ping message functionality. Nothing really stands out in the diff as breaking this. I do see them using the message functionality here though: redis/redis-py@3.2.1...3.3.0#diff-085cbe85ef9bc2ad832d79163eb39172R3187

However the zadd issue appears to be related to how responses are being parsed here Since we were using a lowercase command execution it wasn't being picked up for parsing but now it is:

using redis==3.3.2

>>> rc.zadd('foo', {'a': -0.0})
1
>>> rc.zadd('foo', {'a': 0.0})
0
>>> rc.execute_command('zscore', 'foo', 'a')
-0.0
>>> rc.execute_command('ZSCORE', 'foo', 'a')
-0.0

Using redis==3.2.1

>>> rc.zadd('foo', {'a': -0.0})
1
>>> rc.zadd('foo', {'a': 0.0})
0
>>> rc.execute_command('zscore', 'foo', 'a')
b'-0'
>>> rc.execute_command('ZSCORE', 'foo', 'a')
-0.0

So if we switch that test to using the uppercase command we can expect -0.0 for all versions above 3.0

@bmerry bmerry closed this as completed in ca3c15a Aug 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants