Merge "Allow set_overload to take value as percent"

This commit is contained in:
Jenkins 2015-01-29 06:19:22 +00:00 committed by Gerrit Code Review
commit df529a225f
2 changed files with 80 additions and 25 deletions

View File

@ -256,7 +256,8 @@ swift-ring-builder <builder_file>
balance, dispersion_trailer)
print 'The minimum number of hours before a partition can be ' \
'reassigned is %s' % builder.min_part_hours
print 'The overload factor is %.6f' % builder.overload
print 'The overload factor is %0.2f%% (%.6f)' % (
builder.overload * 100, builder.overload)
if builder.devs:
print 'Devices: id region zone ip address port ' \
'replication ip replication port name ' \
@ -742,7 +743,8 @@ swift-ring-builder <builder_file> dispersion <search_filter> [options]
search_filter = None
report = dispersion_report(builder, search_filter=search_filter,
verbose=options.verbose)
print 'Dispersion is %.06f' % builder.dispersion
print 'Dispersion is %.06f, Balance is %.06f, Overload is %0.2f%%' % (
builder.dispersion, builder.get_balance(), builder.overload * 100)
if report['worst_tier']:
status = EXIT_WARNING
print 'Worst tier is %.06f (%s)' % (report['max_dispersion'],
@ -904,7 +906,7 @@ swift-ring-builder <builder_file> set_replicas <replicas>
def set_overload():
"""
swift-ring-builder <builder_file> set_overload <overload>
swift-ring-builder <builder_file> set_overload <overload>[%]
Changes the overload factor to the given <overload>.
A rebalance is needed to make the change take effect.
@ -914,22 +916,36 @@ swift-ring-builder <builder_file> set_overload <overload>
exit(EXIT_ERROR)
new_overload = argv[3]
if new_overload.endswith('%'):
percent = True
new_overload = new_overload.rstrip('%')
else:
percent = False
try:
new_overload = float(new_overload)
except ValueError:
print Commands.set_overload.__doc__.strip()
print "\"%s\" is not a valid number." % new_overload
print "%r is not a valid number." % new_overload
exit(EXIT_ERROR)
if percent:
new_overload *= 0.01
if new_overload < 0:
print "Overload must be non-negative."
exit(EXIT_ERROR)
if new_overload > 1 and not percent:
print "!?! Warning overload is greater than 100% !?!"
status = EXIT_WARNING
else:
status = EXIT_SUCCESS
builder.set_overload(new_overload)
print 'The overload is now %.6f.' % builder.overload
print 'The overload factor is now %0.2f%% (%.6f)' % (
builder.overload * 100, builder.overload)
print 'The change will take effect after the next rebalance.'
builder.save(argv[1])
exit(EXIT_SUCCESS)
exit(status)
def main(arguments=None):

View File

@ -25,7 +25,25 @@ from swift.common import exceptions
from swift.common.ring import RingBuilder
class TestCommands(unittest.TestCase):
class RunSwiftRingBuilderMixin(object):
def run_srb(self, *argv):
mock_stdout = StringIO.StringIO()
mock_stderr = StringIO.StringIO()
srb_args = ["", self.tempfile] + [str(s) for s in argv]
try:
with mock.patch("sys.stdout", mock_stdout):
with mock.patch("sys.stderr", mock_stderr):
swift.cli.ringbuilder.main(srb_args)
except SystemExit as err:
if err.code not in (0, 1): # (success, warning)
raise
return (mock_stdout.getvalue(), mock_stderr.getvalue())
class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
def __init__(self, *args, **kwargs):
super(TestCommands, self).__init__(*args, **kwargs)
@ -38,7 +56,7 @@ class TestCommands(unittest.TestCase):
"127.0.0.1R127.0.0.1", "R:6000",
"_some meta data"]
tmpf = tempfile.NamedTemporaryFile()
self.tmpfile = tmpf.name
self.tempfile = self.tmpfile = tmpf.name
def tearDown(self):
try:
@ -235,6 +253,42 @@ class TestCommands(unittest.TestCase):
ring = RingBuilder.load(self.tmpfile)
self.assertEqual(ring.overload, 0.0)
def test_set_overload_percent(self):
self.create_sample_ring()
argv = "set_overload 10%".split()
out, err = self.run_srb(*argv)
ring = RingBuilder.load(self.tmpfile)
self.assertEqual(ring.overload, 0.1)
self.assertTrue('10.00%' in out)
self.assertTrue('0.100000' in out)
def test_set_overload_percent_strange_input(self):
self.create_sample_ring()
argv = "set_overload 26%%%%".split()
out, err = self.run_srb(*argv)
ring = RingBuilder.load(self.tmpfile)
self.assertEqual(ring.overload, 0.26)
self.assertTrue('26.00%' in out)
self.assertTrue('0.260000' in out)
def test_server_overload_crazy_high(self):
self.create_sample_ring()
argv = "set_overload 10".split()
out, err = self.run_srb(*argv)
ring = RingBuilder.load(self.tmpfile)
self.assertEqual(ring.overload, 10.0)
self.assertTrue('Warning overload is greater than 100%' in out)
self.assertTrue('1000.00%' in out)
self.assertTrue('10.000000' in out)
# but it's cool if you do it on purpose
argv[-1] = '1000%'
out, err = self.run_srb(*argv)
ring = RingBuilder.load(self.tmpfile)
self.assertEqual(ring.overload, 10.0)
self.assertTrue('Warning overload is greater than 100%' not in out)
self.assertTrue('1000.00%' in out)
self.assertTrue('10.000000' in out)
def test_validate(self):
self.create_sample_ring()
ring = RingBuilder.load(self.tmpfile)
@ -307,12 +361,12 @@ class TestCommands(unittest.TestCase):
self.assertEquals(e.code, 1)
class TestRebalanceCommand(unittest.TestCase):
class TestRebalanceCommand(unittest.TestCase, RunSwiftRingBuilderMixin):
def __init__(self, *args, **kwargs):
super(TestRebalanceCommand, self).__init__(*args, **kwargs)
tmpf = tempfile.NamedTemporaryFile()
self.tempfile = tmpf.name
self.tempfile = self.tmpfile = tmpf.name
def tearDown(self):
try:
@ -320,21 +374,6 @@ class TestRebalanceCommand(unittest.TestCase):
except OSError:
pass
def run_srb(self, *argv):
mock_stdout = StringIO.StringIO()
mock_stderr = StringIO.StringIO()
srb_args = ["", self.tempfile] + [str(s) for s in argv]
try:
with mock.patch("sys.stdout", mock_stdout):
with mock.patch("sys.stderr", mock_stderr):
swift.cli.ringbuilder.main(srb_args)
except SystemExit as err:
if err.code not in (0, 1): # (success, warning)
raise
return (mock_stdout.getvalue(), mock_stderr.getvalue())
def test_rebalance_warning_appears(self):
self.run_srb("create", 8, 3, 24)
# all in one machine: totally balanceable