Merge "s-m-s-r: handle EOFError and KeyboardInterrupt"

This commit is contained in:
Zuul 2022-12-01 21:47:53 +00:00 committed by Gerrit Code Review
commit 20016f2e7b
2 changed files with 82 additions and 22 deletions

View File

@ -233,8 +233,11 @@ def _proceed(args):
elif args.yes: elif args.yes:
choice = 'yes' choice = 'yes'
else: else:
choice = input('Do you want to apply these changes to the container ' try:
'DB? [yes/N]') choice = input('Do you want to apply these changes to the '
'container DB? [yes/N]')
except (EOFError, KeyboardInterrupt):
choice = 'no'
if choice != 'yes': if choice != 'yes':
print('No changes applied') print('No changes applied')
@ -404,9 +407,13 @@ def delete_shard_ranges(broker, args):
print(' - %d existing shard ranges have started sharding' % print(' - %d existing shard ranges have started sharding' %
[sr.state != ShardRange.FOUND [sr.state != ShardRange.FOUND
for sr in shard_ranges].count(True)) for sr in shard_ranges].count(True))
choice = input('Do you want to show the existing ranges [s], ' try:
'delete the existing ranges [yes] ' choice = input('Do you want to show the existing ranges [s], '
'or quit without deleting [q]? ') 'delete the existing ranges [yes] '
'or quit without deleting [q]? ')
except (EOFError, KeyboardInterrupt):
choice = 'q'
if choice == 's': if choice == 's':
show_shard_ranges(broker, args) show_shard_ranges(broker, args)
continue continue

View File

@ -978,6 +978,31 @@ class TestManageShardRanges(unittest.TestCase):
[(data['lower'], data['upper']) for data in self.shard_data], [(data['lower'], data['upper']) for data in self.shard_data],
[(sr.lower_str, sr.upper_str) for sr in broker.get_shard_ranges()]) [(sr.lower_str, sr.upper_str) for sr in broker.get_shard_ranges()])
def check_user_exit(user_input):
# try again now db has shard ranges, simulate user quitting
with open(input_file, 'w') as fd:
json.dump(self.overlap_shard_data_1, fd)
out = StringIO()
err = StringIO()
to_patch = 'swift.cli.manage_shard_ranges.input'
with mock.patch('sys.stdout', out), \
mock.patch('sys.stderr', err), \
mock.patch(to_patch, side_effect=[user_input]):
ret = main([broker.db_file, 'replace', input_file])
self.assertEqual(3, ret)
expected = ['This will delete existing 10 shard ranges.']
self.assertEqual(expected, out.getvalue().splitlines())
self.assertEqual(['Loaded db broker for a/c'],
err.getvalue().splitlines())
self.assertEqual(
[(data['lower'], data['upper']) for data in self.shard_data],
[(sr.lower_str, sr.upper_str)
for sr in broker.get_shard_ranges()])
check_user_exit('q')
check_user_exit(EOFError)
check_user_exit(KeyboardInterrupt)
def test_analyze_stdin(self): def test_analyze_stdin(self):
out = StringIO() out = StringIO()
err = StringIO() err = StringIO()
@ -1154,21 +1179,27 @@ class TestManageShardRanges(unittest.TestCase):
[(data['lower'], data['upper']) for data in self.shard_data], [(data['lower'], data['upper']) for data in self.shard_data],
[(sr.lower_str, sr.upper_str) for sr in found_shard_ranges]) [(sr.lower_str, sr.upper_str) for sr in found_shard_ranges])
# Do another find & replace but quit when prompted about existing def check_user_exit(user_input):
# shard ranges # Do another find & replace but quit when prompted about existing
out = StringIO() # shard ranges
err = StringIO() out = StringIO()
to_patch = 'swift.cli.manage_shard_ranges.input' err = StringIO()
with mock.patch('sys.stdout', out), mock.patch('sys.stderr', err), \ to_patch = 'swift.cli.manage_shard_ranges.input'
mock_timestamp_now(), mock.patch(to_patch, return_value='q'): with mock.patch('sys.stdout', out), mock_timestamp_now(), \
ret = main([broker.db_file, 'find_and_replace', '10']) mock.patch('sys.stderr', err), \
self.assertEqual(3, ret) mock.patch(to_patch, side_effect=[user_input]):
# Shard ranges haven't changed at all ret = main([broker.db_file, 'find_and_replace', '10'])
self.assertEqual(found_shard_ranges, broker.get_shard_ranges()) self.assertEqual(3, ret)
expected = ['This will delete existing 10 shard ranges.'] # Shard ranges haven't changed at all
self.assertEqual(expected, out.getvalue().splitlines()) self.assertEqual(found_shard_ranges, broker.get_shard_ranges())
self.assertEqual(['Loaded db broker for a/c'], expected = ['This will delete existing 10 shard ranges.']
err.getvalue().splitlines()) self.assertEqual(expected, out.getvalue().splitlines())
self.assertEqual(['Loaded db broker for a/c'],
err.getvalue().splitlines())
check_user_exit('q')
check_user_exit(EOFError)
check_user_exit(KeyboardInterrupt)
def test_compact_bad_args(self): def test_compact_bad_args(self):
broker = self._make_broker() broker = self._make_broker()
@ -1327,7 +1358,7 @@ class TestManageShardRanges(unittest.TestCase):
with mock.patch('sys.stdout', out),\ with mock.patch('sys.stdout', out),\
mock.patch('sys.stderr', err), \ mock.patch('sys.stderr', err), \
mock.patch('swift.cli.manage_shard_ranges.input', mock.patch('swift.cli.manage_shard_ranges.input',
return_value=user_input): side_effect=[user_input]):
ret = main([broker.db_file, 'compact', ret = main([broker.db_file, 'compact',
'--max-shrinking', '99'] + options) '--max-shrinking', '99'] + options)
self.assertEqual(exit_code, ret) self.assertEqual(exit_code, ret)
@ -1357,6 +1388,18 @@ class TestManageShardRanges(unittest.TestCase):
for i, sr in enumerate(broker_ranges): for i, sr in enumerate(broker_ranges):
self.assertEqual(ShardRange.ACTIVE, sr.state) self.assertEqual(ShardRange.ACTIVE, sr.state)
broker_ranges = do_compact(EOFError, [], False, 3)
# expect no changes to shard ranges
self.assertEqual(shard_ranges, broker_ranges)
for i, sr in enumerate(broker_ranges):
self.assertEqual(ShardRange.ACTIVE, sr.state)
broker_ranges = do_compact(KeyboardInterrupt, [], False, 3)
# expect no changes to shard ranges
self.assertEqual(shard_ranges, broker_ranges)
for i, sr in enumerate(broker_ranges):
self.assertEqual(ShardRange.ACTIVE, sr.state)
broker_ranges = do_compact('yes', ['--dry-run'], False, 3) broker_ranges = do_compact('yes', ['--dry-run'], False, 3)
# expect no changes to shard ranges # expect no changes to shard ranges
self.assertEqual(shard_ranges, broker_ranges) self.assertEqual(shard_ranges, broker_ranges)
@ -2360,7 +2403,7 @@ class TestManageShardRanges(unittest.TestCase):
mock.patch('sys.stderr', err), \ mock.patch('sys.stderr', err), \
mock_timestamp_now(ts_now), \ mock_timestamp_now(ts_now), \
mock.patch('swift.cli.manage_shard_ranges.input', mock.patch('swift.cli.manage_shard_ranges.input',
return_value=user_input): side_effect=[user_input]):
ret = main( ret = main(
[broker.db_file, 'repair', '--min-shard-age', '0'] + [broker.db_file, 'repair', '--min-shard-age', '0'] +
options) options)
@ -2381,6 +2424,16 @@ class TestManageShardRanges(unittest.TestCase):
key=ShardRange.sort_key) key=ShardRange.sort_key)
self.assert_shard_ranges_equal(expected, updated_ranges) self.assert_shard_ranges_equal(expected, updated_ranges)
ts_now = next(self.ts_iter)
do_repair(EOFError, ts_now, [], 3)
updated_ranges = broker.get_shard_ranges()
self.assert_shard_ranges_equal(expected, updated_ranges)
ts_now = next(self.ts_iter)
do_repair(KeyboardInterrupt, ts_now, [], 3)
updated_ranges = broker.get_shard_ranges()
self.assert_shard_ranges_equal(expected, updated_ranges)
# --dry-run # --dry-run
ts_now = next(self.ts_iter) ts_now = next(self.ts_iter)
do_repair('y', ts_now, ['--dry-run'], 3) do_repair('y', ts_now, ['--dry-run'], 3)