Merge "Mock RingBuilder.rebalance when testing ringbuilder cli warnings"

This commit is contained in:
Jenkins
2017-09-11 23:43:56 +00:00
committed by Gerrit Code Review

View File

@@ -134,7 +134,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
msg += '%3d: %s\n' % (i, line) msg += '%3d: %s\n' % (i, line)
self.fail(msg) self.fail(msg)
def create_sample_ring(self, part_power=6): def create_sample_ring(self, part_power=6, overload=None):
""" """
Create a sample ring with four devices Create a sample ring with four devices
@@ -151,6 +151,8 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
pass pass
ring = RingBuilder(part_power, 3, 1) ring = RingBuilder(part_power, 3, 1)
if overload is not None:
ring.set_overload(overload)
ring.add_dev({'weight': 100.0, ring.add_dev({'weight': 100.0,
'region': 0, 'region': 0,
'zone': 0, 'zone': 0,
@@ -2095,36 +2097,51 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
self.assertIsNone(ringbuilder.main(argv)) self.assertIsNone(ringbuilder.main(argv))
def test_warn_at_risk(self): def test_warn_at_risk(self):
# when the number of total part replicas (3 * 2 ** 4 = 48 in # check that warning is generated when rebalance does not achieve
# this ring) is less than the total units of weight (310 in this # satisfactory balance
# ring) the relative number of parts per unit of weight (called self.create_sample_ring()
# weight_of_one_part) is less than 1 - and each whole part orig_rebalance = RingBuilder.rebalance
# placed takes up a larger ratio of the fractional number of fake_balance = 6
# parts the device wants - so it's much more difficult to
# satisfy a device's weight exactly - that is to say less parts def fake_rebalance(builder_instance, *args, **kwargs):
# to go around tends to make things lumpy parts, balance, removed_devs = orig_rebalance(builder_instance)
self.create_sample_ring(4) return parts, fake_balance, removed_devs
ring = RingBuilder.load(self.tmpfile)
ring.devs[0]['weight'] = 10
ring.save(self.tmpfile)
argv = ["", self.tmpfile, "rebalance"] argv = ["", self.tmpfile, "rebalance"]
self.assertSystemExit(EXIT_WARNING, ringbuilder.main, argv) with mock.patch("swift.common.ring.builder.RingBuilder.rebalance",
fake_rebalance):
self.assertSystemExit(EXIT_WARNING, ringbuilder.main, argv)
# even when some overload is allowed
self.create_sample_ring(overload=0.05)
argv = ["", self.tmpfile, "rebalance"]
with mock.patch("swift.common.ring.builder.RingBuilder.rebalance",
fake_rebalance):
self.assertSystemExit(EXIT_WARNING, ringbuilder.main, argv)
def test_no_warn_when_balanced(self): def test_no_warn_when_balanced(self):
# when the number of total part replicas (3 * 2 ** 10 = 3072 in # check that no warning is generated when satisfactory balance is
# this ring) is larger than the total units of weight (310 in # achieved...
# this ring) the relative number of parts per unit of weight self.create_sample_ring()
# (called weight_of_one_part) is more than 1 - and each whole orig_rebalance = RingBuilder.rebalance
# part placed takes up a smaller ratio of the larger number of fake_balance = 5
# parts the device wants - so it's much easier to satisfy a
# device's weight exactly - that is to say more parts to go def fake_rebalance(builder_instance, *args, **kwargs):
# around tends to smooth things out parts, balance, removed_devs = orig_rebalance(builder_instance)
self.create_sample_ring(10) return parts, fake_balance, removed_devs
ring = RingBuilder.load(self.tmpfile)
ring.devs[0]['weight'] = 10
ring.save(self.tmpfile)
argv = ["", self.tmpfile, "rebalance"] argv = ["", self.tmpfile, "rebalance"]
self.assertSystemExit(EXIT_SUCCESS, ringbuilder.main, argv) with mock.patch("swift.common.ring.builder.RingBuilder.rebalance",
fake_rebalance):
self.assertSystemExit(EXIT_SUCCESS, ringbuilder.main, argv)
# ...or balance is within permitted overload
self.create_sample_ring(overload=0.06)
fake_balance = 6
argv = ["", self.tmpfile, "rebalance"]
with mock.patch("swift.common.ring.builder.RingBuilder.rebalance",
fake_rebalance):
self.assertSystemExit(EXIT_SUCCESS, ringbuilder.main, argv)
def test_invalid_device_name(self): def test_invalid_device_name(self):
self.create_sample_ring() self.create_sample_ring()