Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions RLTest/redis_std.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
_TERMINATE_TIMEOUT = 30
_INSTRUMENTED_TERMINATE_TIMEOUT = 300
_KILL_TIMEOUT = 5
_SAVE_RETRY_TIMEOUT = 10


class StandardEnv(object):
Expand Down Expand Up @@ -659,21 +658,7 @@ def dumpAndReload(self, restart=False, shardId=None, timeout_sec=0):
self.stopEnv()
self.startEnv()
else:
for con in conns:
deadline = time.monotonic() + _SAVE_RETRY_TIMEOUT
while True:
try:
# A concurrent BGSAVE may hold an older snapshot. We still
# need our own successful SAVE before reloading.
con.save()
break
except redis.ResponseError as err:
if str(err) != 'Background save already in progress':
raise
remaining = deadline - time.monotonic()
if remaining <= 0:
raise
time.sleep(min(0.05, remaining))
[con.save() for con in conns]
try:
# Given we've already saved on the prior step, there is no need to SAVE again on the DEBUG RELOAD
[con.execute_command('DEBUG', 'RELOAD', 'NOSAVE') for con in conns]
Expand Down
54 changes: 0 additions & 54 deletions tests/unit/test_redis_std.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
import shutil
import tempfile
from unittest import TestCase
from unittest.mock import Mock, call, patch

import redis

from RLTest.redis_std import StandardEnv
from tests.unit.test_common import REDIS_BINARY, TLS_CERT, TLS_KEY, TLS_CACERT
Expand All @@ -14,57 +11,6 @@
tlsCaCertFile = 'fake_ca.crt'


class TestDumpAndReload(TestCase):
def make_env(self, slave=False):
env = StandardEnv.__new__(StandardEnv)
env.useSlaves = slave
env.getConnection = Mock(return_value=Mock())
env.getSlaveConnection = Mock(return_value=Mock())
return env

@patch('RLTest.redis_std.time.sleep')
def test_busy_save_retries_on_master_and_replica(self, sleep):
env = self.make_env(slave=True)
for conn in (env.getConnection(), env.getSlaveConnection()):
conn.save.side_effect = [
redis.ResponseError('Background save already in progress'), True]
env.dumpAndReload()
for conn in (env.getConnection(), env.getSlaveConnection()):
self.assertEqual(conn.mock_calls, [
call.save(), call.save(),
call.execute_command('DEBUG', 'RELOAD', 'NOSAVE')])
self.assertEqual(sleep.call_count, 2)

@patch('RLTest.redis_std.time.sleep')
@patch('RLTest.redis_std.time.monotonic', side_effect=[0, 10])
def test_busy_save_timeout_does_not_reload(self, monotonic, sleep):
env = self.make_env()
conn = env.getConnection()
error = redis.ResponseError('Background save already in progress')
conn.save.side_effect = error
with self.assertRaises(redis.ResponseError) as raised:
env.dumpAndReload()
self.assertIs(raised.exception, error)
conn.save.assert_called_once_with()
conn.execute_command.assert_not_called()
sleep.assert_not_called()

@patch('RLTest.redis_std.time.sleep')
def test_other_save_errors_are_not_retried(self, sleep):
for error in (redis.ResponseError('Permission denied'),
redis.ConnectionError('Connection lost')):
with self.subTest(error=error):
env = self.make_env()
conn = env.getConnection()
conn.save.side_effect = error
with self.assertRaises(type(error)) as raised:
env.dumpAndReload()
self.assertIs(raised.exception, error)
conn.save.assert_called_once_with()
conn.execute_command.assert_not_called()
sleep.assert_not_called()


class TestStandardEnv(TestCase):

def setUp(self):
Expand Down
Loading