def test_different_part_power_error(self): # create a ring builder # (default, part power is 6 with create_sample_ringbuilders) builders = self.create_sample_ringbuilders(1) # prepare another ring which has different part power incorrect_builder = RingBuilder(4, 3, 1) _, fname = tempfile.mkstemp(dir=self.tmpdir) for _ in range(4): dev = self.pop_region_device(1) incorrect_builder.add_dev(dev) incorrect_builder.rebalance() incorrect_builder.save(fname) # sanity self.assertTrue(os.path.exists(fname)) # sanity correct_builder = builders[0] self.assertNotEqual(correct_builder.part_shift, incorrect_builder.part_shift) self.assertNotEqual(correct_builder.part_power, incorrect_builder.part_power) builders.append(incorrect_builder) with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn("All builders must have same value for 'part_power'", cm.exception.message)
def test_ring_swap(self): # sanity builders = sorted(self.create_sample_ringbuilders(2)) rd = compose_rings(builders) rd.save(self.output_ring) got_ring = Ring(self.output_ring) self.assertEqual(got_ring.partition_count, 2**6) self.assertEqual(got_ring.replica_count, 6) self.assertEqual(got_ring._part_shift, 26) self.assertDevices(got_ring, builders) # even if swapped, it works reverse_builders = sorted(builders, reverse=True) self.assertNotEqual(reverse_builders, builders) rd = compose_rings(reverse_builders) rd.save(self.output_ring) got_ring = Ring(self.output_ring) self.assertEqual(got_ring.partition_count, 2**6) self.assertEqual(got_ring.replica_count, 6) self.assertEqual(got_ring._part_shift, 26) self.assertDevices(got_ring, reverse_builders) # but if the composite rings are different order, the composite ring # *will* be different. Note that the CompositeRingBuilder class will # check builder order against the existing ring and fail if the order # is different (actually checking the metadata). See also # test_compose_different_builder_order with self.assertRaises(AssertionError) as cm: self.assertDevices(got_ring, builders) self.assertIn("composite ring is not ordered by ring order", cm.exception.message)
def test_composite_same_device_in_the_different_rings_error(self): builders = self.create_sample_ringbuilders(2) same_device = copy.deepcopy(builders[0].devs[0]) # create one more ring which duplicates a device in the first ring builder = RingBuilder(6, 3, 1) _, fname = tempfile.mkstemp(dir=self.tmpdir) # add info to feed to add_dev same_device.update({'region': 2, 'weight': 100}) builder.add_dev(same_device) # add rest of the devices, which are unique for _ in range(3): dev = self.pop_region_device(2) builder.add_dev(dev) builder.rebalance() builder.save(fname) # sanity self.assertTrue(os.path.exists(fname)) builders.append(builder) with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn( 'Duplicate ip/port/device combination %(ip)s/%(port)s/%(device)s ' 'found in builders at indexes 0 and 2' % same_device, cm.exception.message)
def test_compose_rings_float_replica_count_builder_error(self): builders = self.create_sample_ringbuilders(1) # prepare another ring which has float replica count incorrect_builder = RingBuilder(6, 1.5, 1) _, fname = tempfile.mkstemp(dir=self.tmpdir) for _ in range(4): dev = self.pop_region_device(1) incorrect_builder.add_dev(dev) incorrect_builder.rebalance() incorrect_builder.save(fname) # sanity self.assertTrue(os.path.exists(fname)) self.assertEqual(1.5, incorrect_builder.replicas) # the first replica has 2 ** 6 partitions self.assertEqual( 2 ** 6, len(incorrect_builder._replica2part2dev[0])) # but the second replica has the half of the first partitions self.assertEqual( 2 ** 5, len(incorrect_builder._replica2part2dev[1])) builders.append(incorrect_builder) with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn("Problem with builders", cm.exception.message) self.assertIn("Non integer replica count", cm.exception.message)
def test_composite_only_one_ring_in_the_args_error(self): builders = self.create_sample_ringbuilders(1) with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn( 'Two or more component builders are required.', cm.exception.message)
def test_composite_same_region_in_the_different_rings_error(self): builder_1 = self.create_sample_ringbuilders(1) builder_2 = self.create_sample_ringbuilders(1) builders = builder_1 + builder_2 with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn('Same region found in different rings', cm.exception.message)
def test_compose_rings_rebalance_needed(self): builders = self.create_sample_ringbuilders(2) # add a new device to builider 1 but no rebalance dev = self.pop_region_device(1) builders[1].add_dev(dev) self.assertTrue(builders[1].devs_changed) # sanity check with self.assertRaises(ValueError) as cm: compose_rings(builders) self.assertIn("Problem with builders", cm.exception.message) self.assertIn("Builder needs rebalance", cm.exception.message) # after rebalance, that works (sanity) builders[1].rebalance() compose_rings(builders)
def test_different_replica_count_works(self): # create a ring builder # (default, part power is 6 with create_sample_ringbuilders) builders = self.create_sample_ringbuilders(1) # prepare another ring which has different replica count builder = RingBuilder(6, 1, 1) _, fname = tempfile.mkstemp(dir=self.tmpdir) for _ in range(4): dev = self.pop_region_device(1) builder.add_dev(dev) builder.rebalance() builder.save(fname) # sanity self.assertTrue(os.path.exists(fname)) builders.append(builder) rd = compose_rings(builders) rd.save(self.output_ring) got_ring = Ring(self.output_ring) self.assertEqual(got_ring.partition_count, 2**6) self.assertEqual(got_ring.replica_count, 4) # 3 + 1 self.assertEqual(got_ring._part_shift, 26) self.assertDevices(got_ring, builders)
def do_test(builder_count): builders = self.create_sample_ringbuilders(builder_count) rd = compose_rings(builders) rd.save(self.output_ring) self.check_composite_ring(self.output_ring, builders)