def test_multiple_names(self): # checking duplicate on insert test_policies = [StoragePolicy(0, 'zero', True), StoragePolicy(1, 'one', False, aliases='zero')] self.assertRaises(PolicyError, StoragePolicyCollection, test_policies) # checking correct retrival using other names test_policies = [StoragePolicy(0, 'zero', True, aliases='cero, kore'), StoragePolicy(1, 'one', False, aliases='uno, tahi'), StoragePolicy(2, 'two', False, aliases='dos, rua')] policies = StoragePolicyCollection(test_policies) for name in ('zero', 'cero', 'kore'): self.assertEqual(policies.get_by_name(name), test_policies[0]) for name in ('two', 'dos', 'rua'): self.assertEqual(policies.get_by_name(name), test_policies[2]) # Testing parsing of conf files/text good_conf = self._conf(""" [storage-policy:0] name = one aliases = uno, tahi default = yes """) policies = parse_storage_policies(good_conf) self.assertEqual(policies.get_by_name('one'), policies[0]) self.assertEqual(policies.get_by_name('one'), policies.get_by_name('tahi')) name_repeat_conf = self._conf(""" [storage-policy:0] name = one aliases = one default = yes """) # Test on line below should not generate errors. Repeat of main # name under aliases is permitted during construction # but only because automated testing requires it. policies = parse_storage_policies(name_repeat_conf) bad_conf = self._conf(""" [storage-policy:0] name = one aliases = uno, uno default = yes """) self.assertRaisesWithMessage(PolicyError, 'is already assigned to this policy', parse_storage_policies, bad_conf)
def test_no_default(self): orig_conf = self._conf( """ [storage-policy:0] name = zero [storage-policy:1] name = one default = yes """ ) policies = parse_storage_policies(orig_conf) self.assertEqual(policies.default, policies[1]) self.assertTrue(policies[0].name, "Policy-0") bad_conf = self._conf( """ [storage-policy:0] name = zero [storage-policy:1] name = one deprecated = yes """ ) # multiple polices and no explicit default self.assertRaisesWithMessage(PolicyError, "Unable to find default", parse_storage_policies, bad_conf) good_conf = self._conf( """ [storage-policy:0] name = Policy-0 default = yes [storage-policy:1] name = one deprecated = yes """ ) policies = parse_storage_policies(good_conf) self.assertEqual(policies.default, policies[0]) self.assertTrue(policies[1].is_deprecated, True)
def test_no_default(self): orig_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = one default = yes """) policies = parse_storage_policies(orig_conf) self.assertEqual(policies.default, policies[1]) self.assertTrue(policies[0].name, 'Policy-0') bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = one deprecated = yes """) # multiple polices and no explicit default self.assertRaisesWithMessage( PolicyError, "Unable to find default", parse_storage_policies, bad_conf) good_conf = self._conf(""" [storage-policy:0] name = Policy-0 default = yes [storage-policy:1] name = one deprecated = yes """) policies = parse_storage_policies(good_conf) self.assertEqual(policies.default, policies[0]) self.assertTrue(policies[1].is_deprecated, True)
def _in_process_setup_ring(swift_conf, conf_src_dir, testdir): """ If SWIFT_TEST_POLICY is set: - look in swift.conf file for specified policy - move this to be policy-0 but preserving its options - copy its ring file to test dir, changing its devices to suit in process testing, and renaming it to suit policy-0 Otherwise, create a default ring file. """ conf = ConfigParser() conf.read(swift_conf) sp_prefix = 'storage-policy:' try: # policy index 0 will be created if no policy exists in conf policies = parse_storage_policies(conf) except PolicyError as e: raise InProcessException(e) # clear all policies from test swift.conf before adding test policy back for policy in policies: conf.remove_section(sp_prefix + str(policy.idx)) if policy_specified: policy_to_test = policies.get_by_name(policy_specified) if policy_to_test is None: raise InProcessException('Failed to find policy name "%s"' % policy_specified) _info('Using specified policy %s' % policy_to_test.name) else: policy_to_test = policies.default _info('Defaulting to policy %s' % policy_to_test.name) # make policy_to_test be policy index 0 and default for the test config sp_zero_section = sp_prefix + '0' conf.add_section(sp_zero_section) for (k, v) in policy_to_test.get_info(config=True).items(): conf.set(sp_zero_section, k, str(v)) conf.set(sp_zero_section, 'default', 'True') with open(swift_conf, 'w') as fp: conf.write(fp) # look for a source ring file ring_file_src = ring_file_test = 'object.ring.gz' if policy_to_test.idx: ring_file_src = 'object-%s.ring.gz' % policy_to_test.idx try: ring_file_src = _in_process_find_conf_file(conf_src_dir, ring_file_src, use_sample=False) except InProcessException as e: if policy_specified: raise InProcessException('Failed to find ring file %s' % ring_file_src) ring_file_src = None ring_file_test = os.path.join(testdir, ring_file_test) if ring_file_src: # copy source ring file to a policy-0 test ring file, re-homing servers _info('Using source ring file %s' % ring_file_src) ring_data = ring.RingData.load(ring_file_src) obj_sockets = [] for dev in ring_data.devs: device = 'sd%c1' % chr(len(obj_sockets) + ord('a')) utils.mkdirs(os.path.join(_testdir, 'sda1')) utils.mkdirs(os.path.join(_testdir, 'sda1', 'tmp')) obj_socket = listen_zero() obj_sockets.append(obj_socket) dev['port'] = obj_socket.getsockname()[1] dev['ip'] = '127.0.0.1' dev['device'] = device dev['replication_port'] = dev['port'] dev['replication_ip'] = dev['ip'] ring_data.save(ring_file_test) else: # make default test ring, 3 replicas, 4 partitions, 3 devices # which will work for a replication policy or a 2+1 EC policy _info('No source object ring file, creating 3rep/4part/3dev ring') obj_sockets = [listen_zero() for _ in (0, 1, 2)] replica2part2dev_id = [[0, 1, 2, 0], [1, 2, 0, 1], [2, 0, 1, 2]] devs = [{'id': 0, 'zone': 0, 'device': 'sda1', 'ip': '127.0.0.1', 'port': obj_sockets[0].getsockname()[1]}, {'id': 1, 'zone': 1, 'device': 'sdb1', 'ip': '127.0.0.1', 'port': obj_sockets[1].getsockname()[1]}, {'id': 2, 'zone': 2, 'device': 'sdc1', 'ip': '127.0.0.1', 'port': obj_sockets[2].getsockname()[1]}] ring_data = ring.RingData(replica2part2dev_id, devs, 30) with closing(GzipFile(ring_file_test, 'wb')) as f: pickle.dump(ring_data, f) for dev in ring_data.devs: _debug('Ring file dev: %s' % dev) return obj_sockets
def test_parse_storage_policies(self): # ValueError when deprecating policy 0 bad_conf = self._conf(""" [storage-policy:0] name = zero deprecated = yes [storage-policy:1] name = one deprecated = yes """) self.assertRaisesWithMessage( PolicyError, "Unable to find policy that's not deprecated", parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x:1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = zero boo = berries """) self.assertRaisesWithMessage(PolicyError, 'Invalid option', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:3] name = Policy-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = policY-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = one [storage-policy:1] name = ONE """) self.assertRaisesWithMessage(PolicyError, 'Duplicate name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = good_stuff """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) # Additional section added to ensure parser ignores other sections conf = self._conf(""" [some-other-section] foo = bar [storage-policy:0] name = zero [storage-policy:5] name = one default = yes [storage-policy:6] name = duplicate-sections-are-ignored [storage-policy:6] name = apple """) policies = parse_storage_policies(conf) self.assertEquals(True, policies.get_by_index(5).is_default) self.assertEquals(False, policies.get_by_index(0).is_default) self.assertEquals(False, policies.get_by_index(6).is_default) self.assertEquals("object", policies.get_by_name("zero").ring_name) self.assertEquals("object-5", policies.get_by_name("one").ring_name) self.assertEquals("object-6", policies.get_by_name("apple").ring_name) self.assertEqual(0, int(policies.get_by_name('zero'))) self.assertEqual(5, int(policies.get_by_name('one'))) self.assertEqual(6, int(policies.get_by_name('apple'))) self.assertEquals("zero", policies.get_by_index(0).name) self.assertEquals("zero", policies.get_by_index("0").name) self.assertEquals("one", policies.get_by_index(5).name) self.assertEquals("apple", policies.get_by_index(6).name) self.assertEquals("zero", policies.get_by_index(None).name) self.assertEquals("zero", policies.get_by_index('').name)
def test_parse_storage_policies(self): # ValueError when deprecating policy 0 bad_conf = self._conf(""" [storage-policy:0] name = zero deprecated = yes [storage-policy:1] name = one deprecated = yes """) self.assertRaisesWithMessage( PolicyError, "Unable to find policy that's not deprecated", parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x:1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = zero boo = berries """) self.assertRaisesWithMessage(PolicyError, 'Invalid option', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:3] name = Policy-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = policY-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = one [storage-policy:1] name = ONE """) self.assertRaisesWithMessage(PolicyError, 'Duplicate name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = good_stuff """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) # policy_type = erasure_coding # missing ec_type, ec_num_data_fragments and ec_num_parity_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding """) self.assertRaisesWithMessage(PolicyError, 'Missing ec_type', parse_storage_policies, bad_conf) # missing ec_type, but other options valid... bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """) self.assertRaisesWithMessage(PolicyError, 'Missing ec_type', parse_storage_policies, bad_conf) # ec_type specified, but invalid... bad_conf = self._conf(""" [storage-policy:0] name = zero default = yes [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = garbage_alg ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """) self.assertRaisesWithMessage(PolicyError, 'Wrong ec_type garbage_alg for policy ' 'ec10-4, should be one of "%s"' % (', '.join(VALID_EC_TYPES)), parse_storage_policies, bad_conf) # missing and invalid ec_num_parity_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = %(ec_type)s ec_num_data_fragments = 10 """ % {'ec_type': DEFAULT_TEST_EC_TYPE}) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_parity_fragments', parse_storage_policies, bad_conf) for num_parity in ('-4', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = %(ec_type)s ec_num_data_fragments = 10 ec_num_parity_fragments = %(num_parity)s """ % {'ec_type': DEFAULT_TEST_EC_TYPE, 'num_parity': num_parity}) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_parity_fragments', parse_storage_policies, bad_conf) # missing and invalid ec_num_data_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = %(ec_type)s ec_num_parity_fragments = 4 """ % {'ec_type': DEFAULT_TEST_EC_TYPE}) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_data_fragments', parse_storage_policies, bad_conf) for num_data in ('-10', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = %(ec_type)s ec_num_data_fragments = %(num_data)s ec_num_parity_fragments = 4 """ % {'num_data': num_data, 'ec_type': DEFAULT_TEST_EC_TYPE}) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_data_fragments', parse_storage_policies, bad_conf) # invalid ec_object_segment_size for segment_size in ('-4', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_object_segment_size = %(segment_size)s ec_type = %(ec_type)s ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """ % {'segment_size': segment_size, 'ec_type': DEFAULT_TEST_EC_TYPE}) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_object_segment_size', parse_storage_policies, bad_conf) # Additional section added to ensure parser ignores other sections conf = self._conf(""" [some-other-section] foo = bar [storage-policy:0] name = zero [storage-policy:5] name = one default = yes [storage-policy:6] name = duplicate-sections-are-ignored [storage-policy:6] name = apple """) policies = parse_storage_policies(conf) self.assertEqual(True, policies.get_by_index(5).is_default) self.assertEqual(False, policies.get_by_index(0).is_default) self.assertEqual(False, policies.get_by_index(6).is_default) self.assertEqual("object", policies.get_by_name("zero").ring_name) self.assertEqual("object-5", policies.get_by_name("one").ring_name) self.assertEqual("object-6", policies.get_by_name("apple").ring_name) self.assertEqual(0, int(policies.get_by_name('zero'))) self.assertEqual(5, int(policies.get_by_name('one'))) self.assertEqual(6, int(policies.get_by_name('apple'))) self.assertEqual("zero", policies.get_by_index(0).name) self.assertEqual("zero", policies.get_by_index("0").name) self.assertEqual("one", policies.get_by_index(5).name) self.assertEqual("apple", policies.get_by_index(6).name) self.assertEqual("zero", policies.get_by_index(None).name) self.assertEqual("zero", policies.get_by_index('').name) self.assertEqual(policies.get_by_index(0), policies.legacy)
def test_multiple_names_EC(self): # checking duplicate names on insert test_policies_ec = [ ECStoragePolicy( 0, 'ec8-2', aliases='zeus, jupiter', ec_type=DEFAULT_TEST_EC_TYPE, ec_ndata=8, ec_nparity=2, object_ring=FakeRing(replicas=8), is_default=True), ECStoragePolicy( 1, 'ec10-4', aliases='ec8-2', ec_type=DEFAULT_TEST_EC_TYPE, ec_ndata=10, ec_nparity=4, object_ring=FakeRing(replicas=10))] self.assertRaises(PolicyError, StoragePolicyCollection, test_policies_ec) # checking correct retrival using other names good_test_policies_EC = [ ECStoragePolicy(0, 'ec8-2', aliases='zeus, jupiter', ec_type=DEFAULT_TEST_EC_TYPE, ec_ndata=8, ec_nparity=2, object_ring=FakeRing(replicas=8), is_default=True), ECStoragePolicy(1, 'ec10-4', aliases='athena, minerva', ec_type=DEFAULT_TEST_EC_TYPE, ec_ndata=10, ec_nparity=4, object_ring=FakeRing(replicas=10)), ECStoragePolicy(2, 'ec4-2', aliases='poseidon, neptune', ec_type=DEFAULT_TEST_EC_TYPE, ec_ndata=4, ec_nparity=2, object_ring=FakeRing(replicas=7)), ] ec_policies = StoragePolicyCollection(good_test_policies_EC) for name in ('ec8-2', 'zeus', 'jupiter'): self.assertEqual(ec_policies.get_by_name(name), ec_policies[0]) for name in ('ec10-4', 'athena', 'minerva'): self.assertEqual(ec_policies.get_by_name(name), ec_policies[1]) # Testing parsing of conf files/text good_ec_conf = self._conf(""" [storage-policy:0] name = ec8-2 aliases = zeus, jupiter policy_type = erasure_coding ec_type = %(ec_type)s default = yes ec_num_data_fragments = 8 ec_num_parity_fragments = 2 [storage-policy:1] name = ec10-4 aliases = poseidon, neptune policy_type = erasure_coding ec_type = %(ec_type)s ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """ % {'ec_type': DEFAULT_TEST_EC_TYPE}) ec_policies = parse_storage_policies(good_ec_conf) self.assertEqual(ec_policies.get_by_name('ec8-2'), ec_policies[0]) self.assertEqual(ec_policies.get_by_name('ec10-4'), ec_policies.get_by_name('poseidon')) name_repeat_ec_conf = self._conf(""" [storage-policy:0] name = ec8-2 aliases = ec8-2 policy_type = erasure_coding ec_type = %(ec_type)s default = yes ec_num_data_fragments = 8 ec_num_parity_fragments = 2 """ % {'ec_type': DEFAULT_TEST_EC_TYPE}) # Test on line below should not generate errors. Repeat of main # name under aliases is permitted during construction # but only because automated testing requires it. ec_policies = parse_storage_policies(name_repeat_ec_conf) bad_ec_conf = self._conf(""" [storage-policy:0] name = ec8-2 aliases = zeus, zeus policy_type = erasure_coding ec_type = %(ec_type)s default = yes ec_num_data_fragments = 8 ec_num_parity_fragments = 2 """ % {'ec_type': DEFAULT_TEST_EC_TYPE}) self.assertRaisesWithMessage(PolicyError, 'is already assigned to this policy', parse_storage_policies, bad_ec_conf)
def _in_process_setup_ring(swift_conf, conf_src_dir, testdir): """ If SWIFT_TEST_POLICY is set: - look in swift.conf file for specified policy - move this to be policy-0 but preserving its options - copy its ring file to test dir, changing its devices to suit in process testing, and renaming it to suit policy-0 Otherwise, create a default ring file. """ conf = ConfigParser() conf.read(swift_conf) sp_prefix = 'storage-policy:' try: # policy index 0 will be created if no policy exists in conf policies = parse_storage_policies(conf) except PolicyError as e: raise InProcessException(e) # clear all policies from test swift.conf before adding test policy back for policy in policies: conf.remove_section(sp_prefix + str(policy.idx)) if policy_specified: policy_to_test = policies.get_by_name(policy_specified) if policy_to_test is None: raise InProcessException('Failed to find policy name "%s"' % policy_specified) _info('Using specified policy %s' % policy_to_test.name) else: policy_to_test = policies.default _info('Defaulting to policy %s' % policy_to_test.name) # make policy_to_test be policy index 0 and default for the test config sp_zero_section = sp_prefix + '0' conf.add_section(sp_zero_section) for (k, v) in policy_to_test.get_info(config=True).items(): conf.set(sp_zero_section, k, v) conf.set(sp_zero_section, 'default', True) with open(swift_conf, 'w') as fp: conf.write(fp) # look for a source ring file ring_file_src = ring_file_test = 'object.ring.gz' if policy_to_test.idx: ring_file_src = 'object-%s.ring.gz' % policy_to_test.idx try: ring_file_src = _in_process_find_conf_file(conf_src_dir, ring_file_src, use_sample=False) except InProcessException as e: if policy_specified: raise InProcessException('Failed to find ring file %s' % ring_file_src) ring_file_src = None ring_file_test = os.path.join(testdir, ring_file_test) if ring_file_src: # copy source ring file to a policy-0 test ring file, re-homing servers _info('Using source ring file %s' % ring_file_src) ring_data = ring.RingData.load(ring_file_src) obj_sockets = [] for dev in ring_data.devs: device = 'sd%c1' % chr(len(obj_sockets) + ord('a')) utils.mkdirs(os.path.join(_testdir, 'sda1')) utils.mkdirs(os.path.join(_testdir, 'sda1', 'tmp')) obj_socket = listen_zero() obj_sockets.append(obj_socket) dev['port'] = obj_socket.getsockname()[1] dev['ip'] = '127.0.0.1' dev['device'] = device dev['replication_port'] = dev['port'] dev['replication_ip'] = dev['ip'] ring_data.save(ring_file_test) else: # make default test ring, 3 replicas, 4 partitions, 3 devices # which will work for a replication policy or a 2+1 EC policy _info('No source object ring file, creating 3rep/4part/3dev ring') obj_sockets = [listen_zero() for _ in (0, 1, 2)] replica2part2dev_id = [[0, 1, 2, 0], [1, 2, 0, 1], [2, 0, 1, 2]] devs = [{'id': 0, 'zone': 0, 'device': 'sda1', 'ip': '127.0.0.1', 'port': obj_sockets[0].getsockname()[1]}, {'id': 1, 'zone': 1, 'device': 'sdb1', 'ip': '127.0.0.1', 'port': obj_sockets[1].getsockname()[1]}, {'id': 2, 'zone': 2, 'device': 'sdc1', 'ip': '127.0.0.1', 'port': obj_sockets[2].getsockname()[1]}] ring_data = ring.RingData(replica2part2dev_id, devs, 30) with closing(GzipFile(ring_file_test, 'wb')) as f: pickle.dump(ring_data, f) for dev in ring_data.devs: _debug('Ring file dev: %s' % dev) return obj_sockets
def test_parse_storage_policies(self): # ValueError when deprecating policy 0 bad_conf = self._conf(""" [storage-policy:0] name = zero deprecated = yes [storage-policy:1] name = one deprecated = yes """) self.assertRaisesWithMessage( PolicyError, "Unable to find policy that's not deprecated", parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x-1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:x:1] name = zero """) self.assertRaisesWithMessage(PolicyError, 'Invalid index', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = zero boo = berries """) self.assertRaisesWithMessage(PolicyError, 'Invalid option', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:3] name = Policy-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:1] name = policY-0 """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = one [storage-policy:1] name = ONE """) self.assertRaisesWithMessage(PolicyError, 'Duplicate name', parse_storage_policies, bad_conf) bad_conf = self._conf(""" [storage-policy:0] name = good_stuff """) self.assertRaisesWithMessage(PolicyError, 'Invalid name', parse_storage_policies, bad_conf) # policy_type = erasure_coding # missing ec_type, ec_num_data_fragments and ec_num_parity_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding """) self.assertRaisesWithMessage(PolicyError, 'Missing ec_type', parse_storage_policies, bad_conf) # missing ec_type, but other options valid... bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """) self.assertRaisesWithMessage(PolicyError, 'Missing ec_type', parse_storage_policies, bad_conf) # ec_type specified, but invalid... bad_conf = self._conf(""" [storage-policy:0] name = zero default = yes [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = garbage_alg ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """) self.assertRaisesWithMessage( PolicyError, 'Wrong ec_type garbage_alg for policy ' 'ec10-4, should be one of "%s"' % (', '.join(VALID_EC_TYPES)), parse_storage_policies, bad_conf) # missing and invalid ec_num_parity_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = jerasure_rs_vand ec_num_data_fragments = 10 """) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_parity_fragments', parse_storage_policies, bad_conf) for num_parity in ('-4', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = jerasure_rs_vand ec_num_data_fragments = 10 ec_num_parity_fragments = %s """ % num_parity) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_parity_fragments', parse_storage_policies, bad_conf) # missing and invalid ec_num_data_fragments bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = jerasure_rs_vand ec_num_parity_fragments = 4 """) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_data_fragments', parse_storage_policies, bad_conf) for num_data in ('-10', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_type = jerasure_rs_vand ec_num_data_fragments = %s ec_num_parity_fragments = 4 """ % num_data) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_num_data_fragments', parse_storage_policies, bad_conf) # invalid ec_object_segment_size for segment_size in ('-4', '0', 'x'): bad_conf = self._conf(""" [storage-policy:0] name = zero [storage-policy:1] name = ec10-4 policy_type = erasure_coding ec_object_segment_size = %s ec_type = jerasure_rs_vand ec_num_data_fragments = 10 ec_num_parity_fragments = 4 """ % segment_size) self.assertRaisesWithMessage(PolicyError, 'Invalid ec_object_segment_size', parse_storage_policies, bad_conf) # Additional section added to ensure parser ignores other sections conf = self._conf(""" [some-other-section] foo = bar [storage-policy:0] name = zero [storage-policy:5] name = one default = yes [storage-policy:6] name = duplicate-sections-are-ignored [storage-policy:6] name = apple """) policies = parse_storage_policies(conf) self.assertEquals(True, policies.get_by_index(5).is_default) self.assertEquals(False, policies.get_by_index(0).is_default) self.assertEquals(False, policies.get_by_index(6).is_default) self.assertEquals("object", policies.get_by_name("zero").ring_name) self.assertEquals("object-5", policies.get_by_name("one").ring_name) self.assertEquals("object-6", policies.get_by_name("apple").ring_name) self.assertEqual(0, int(policies.get_by_name('zero'))) self.assertEqual(5, int(policies.get_by_name('one'))) self.assertEqual(6, int(policies.get_by_name('apple'))) self.assertEquals("zero", policies.get_by_index(0).name) self.assertEquals("zero", policies.get_by_index("0").name) self.assertEquals("one", policies.get_by_index(5).name) self.assertEquals("apple", policies.get_by_index(6).name) self.assertEquals("zero", policies.get_by_index(None).name) self.assertEquals("zero", policies.get_by_index('').name) self.assertEqual(policies.get_by_index(0), policies.legacy)
def test_multiple_names(self): # checking duplicate on insert test_policies = [StoragePolicy(0, 'zero', True), StoragePolicy(1, 'one', False, aliases='zero')] self.assertRaises(PolicyError, StoragePolicyCollection, test_policies) # checking correct retrival using other names test_policies = [StoragePolicy(0, 'zero', True, aliases='cero, kore'), StoragePolicy(1, 'one', False, aliases='uno, tahi'), StoragePolicy(2, 'two', False, aliases='dos, rua')] policies = StoragePolicyCollection(test_policies) for name in ('zero', 'cero', 'kore'): self.assertEqual(policies.get_by_name(name), test_policies[0]) for name in ('two', 'dos', 'rua'): self.assertEqual(policies.get_by_name(name), test_policies[2]) # Testing parsing of conf files/text good_conf = self._conf(""" [storage-policy:0] name = one aliases = uno, tahi default = yes """) policies = parse_storage_policies(good_conf) self.assertEqual(policies.get_by_name('one'), policies[0]) self.assertEqual(policies.get_by_name('one'), policies.get_by_name('tahi')) name_repeat_conf = self._conf(""" [storage-policy:0] name = one aliases = one default = yes """) # Test on line below should not generate errors. Repeat of main # name under aliases is permitted during construction # but only because automated testing requires it. policies = parse_storage_policies(name_repeat_conf) extra_commas_conf = self._conf(""" [storage-policy:0] name = one aliases = ,,one, , default = yes """) # Extra blank entries should be silently dropped policies = parse_storage_policies(extra_commas_conf) bad_conf = self._conf(""" [storage-policy:0] name = one aliases = uno, uno default = yes """) self.assertRaisesWithMessage(PolicyError, 'is already assigned to this policy', parse_storage_policies, bad_conf)
def _in_process_setup_ring(swift_conf, conf_src_dir, testdir): """ If SWIFT_TEST_POLICY is set: - look in swift.conf file for specified policy - move this to be policy-0 but preserving its options - copy its ring file to test dir, changing its devices to suit in process testing, and renaming it to suit policy-0 Otherwise, create a default ring file. """ conf = ConfigParser() conf.read(swift_conf) sp_prefix = "storage-policy:" try: # policy index 0 will be created if no policy exists in conf policies = parse_storage_policies(conf) except PolicyError as e: raise InProcessException(e) # clear all policies from test swift.conf before adding test policy back for policy in policies: conf.remove_section(sp_prefix + str(policy.idx)) if policy_specified: policy_to_test = policies.get_by_name(policy_specified) if policy_to_test is None: raise InProcessException('Failed to find policy name "%s"' % policy_specified) _info("Using specified policy %s" % policy_to_test.name) else: policy_to_test = policies.default _info("Defaulting to policy %s" % policy_to_test.name) # make policy_to_test be policy index 0 and default for the test config sp_zero_section = sp_prefix + "0" conf.add_section(sp_zero_section) for (k, v) in policy_to_test.get_info(config=True).items(): conf.set(sp_zero_section, k, v) conf.set(sp_zero_section, "default", True) with open(swift_conf, "w") as fp: conf.write(fp) # look for a source ring file ring_file_src = ring_file_test = "object.ring.gz" if policy_to_test.idx: ring_file_src = "object-%s.ring.gz" % policy_to_test.idx try: ring_file_src = _in_process_find_conf_file(conf_src_dir, ring_file_src, use_sample=False) except InProcessException as e: if policy_specified: raise InProcessException("Failed to find ring file %s" % ring_file_src) ring_file_src = None ring_file_test = os.path.join(testdir, ring_file_test) if ring_file_src: # copy source ring file to a policy-0 test ring file, re-homing servers _info("Using source ring file %s" % ring_file_src) ring_data = ring.RingData.load(ring_file_src) obj_sockets = [] for dev in ring_data.devs: device = "sd%c1" % chr(len(obj_sockets) + ord("a")) utils.mkdirs(os.path.join(_testdir, "sda1")) utils.mkdirs(os.path.join(_testdir, "sda1", "tmp")) obj_socket = eventlet.listen(("localhost", 0)) obj_sockets.append(obj_socket) dev["port"] = obj_socket.getsockname()[1] dev["ip"] = "127.0.0.1" dev["device"] = device dev["replication_port"] = dev["port"] dev["replication_ip"] = dev["ip"] ring_data.save(ring_file_test) else: # make default test ring, 2 replicas, 4 partitions, 2 devices _info("No source object ring file, creating 2rep/4part/2dev ring") obj_sockets = [eventlet.listen(("localhost", 0)) for _ in (0, 1)] ring_data = ring.RingData( [[0, 1, 0, 1], [1, 0, 1, 0]], [ {"id": 0, "zone": 0, "device": "sda1", "ip": "127.0.0.1", "port": obj_sockets[0].getsockname()[1]}, {"id": 1, "zone": 1, "device": "sdb1", "ip": "127.0.0.1", "port": obj_sockets[1].getsockname()[1]}, ], 30, ) with closing(GzipFile(ring_file_test, "wb")) as f: pickle.dump(ring_data, f) for dev in ring_data.devs: _debug("Ring file dev: %s" % dev) return obj_sockets