def setUp(self): base_config = "low-level/files/opt/seagate/sspl/conf/sspl.conf.LR2.yaml" base_config = os.path.dirname(os.path.abspath(__file__)).replace( "unittests/framework/base", base_config) base_config_url = f"yaml://{base_config}" self.tmp_dir = "/opt/seagate/cortx/sspl/tmp" self.existing_config = f"/{self.tmp_dir}/existing.conf" self.new_config = f"/{self.tmp_dir}/new.conf" self.merged_config = f"/{self.tmp_dir}/merged.conf" os.makedirs(self.tmp_dir, exist_ok=True) with open(self.existing_config, "w"): pass with open(self.new_config, "w"): pass self.existing_config_url = f"yaml://{self.existing_config}" self.new_config_url = f"yaml://{self.new_config}" self.merged_config_url = f"yaml://{self.merged_config}" Conf.load("base", base_config_url) Conf.load("existing", self.existing_config_url) Conf.load("new", self.new_config_url) # Delete below keys to get clean config Conf.delete("base", "CHANGED") Conf.delete("base", "OBSOLETE") # Create exising and new config file from base file Conf.copy("base", "existing") Conf.copy("base", "new") Conf.save("existing") Conf.save("new")
def test_set_delete_and_get(self): """ Get a deleted key. """ for index in TestConfStore.indexes: Conf.set(index, 'K1', 'V1') Conf.delete(index, 'K1') val = Conf.get(index, 'K1') self.assertEqual(val, None)
def upgrade(config_path: str, change_set_path: str): """Perform upgrade steps.""" Conf.load(DELTA_INDEX, change_set_path) Conf.load(GCONF_INDEX, config_path, skip_reload=True) delta_keys = Conf.get_keys(DELTA_INDEX) # if message_bus_backend changed, add new and delete old msg bus entries if CHANGED_PREFIX + MSG_BUS_BACKEND_KEY in delta_keys: new_msg_bus_backend = Conf.get( DELTA_INDEX, CHANGED_PREFIX + MSG_BUS_BACKEND_KEY).split('|')[1] Conf.set(GCONF_INDEX, MSG_BUS_BACKEND_KEY, new_msg_bus_backend) for key in delta_keys: if NEW_PREFIX + EXTERNAL_KEY + new_msg_bus_backend in key: new_key = key.split(NEW_PREFIX)[1] new_val = Conf.get(DELTA_INDEX, key).split('|')[1] Conf.set(GCONF_INDEX, new_key, new_val) if DELETED_PREFIX + EXTERNAL_KEY + new_msg_bus_backend in key: delete_key = key.split(DELETED_PREFIX)[1] Conf.delete(GCONF_INDEX, delete_key) # update existing messagebus parameters else: msg_bus_backend = Conf.get(GCONF_INDEX, MSG_BUS_BACKEND_KEY) for key in delta_keys: if CHANGED_PREFIX + EXTERNAL_KEY + msg_bus_backend in key: new_val = Conf.get(DELTA_INDEX, key).split('|')[1] change_key = key.split(CHANGED_PREFIX)[1] Conf.set(GCONF_INDEX, change_key, new_val) Conf.save(GCONF_INDEX) Utils.init(config_path) return 0
def test_conf_store_delete(self): """ Test by removing the key, value to given index and reading it back. """ load_config('delete_local', 'json:///tmp/file1.json') Conf.delete('delete_local', 'bridge>proxy') result_data = Conf.get('delete_local', 'bridge>proxy') self.assertEqual(result_data, None)
def test_get_keys_delete(self): """Test get_keys after deletion of a key.""" load_config('get_keys_delete', 'json:///tmp/file1.json') Conf.set('get_keys_delete', 'bridge>delete>key', 'del_val') pre_key_list = Conf.get_keys('get_keys_delete') Conf.delete('get_keys_delete', 'bridge>delete>key') post_key_list = Conf.get_keys('get_keys_delete') self.assertTrue(pre_key_list != post_key_list)
def test_json_message_kv_store(self): """Tests jsonmessage basic operation.""" index = 'json_message_kv_store_index' Conf.load(index, 'jsonmessage:{"key1":"val1"}') self.assertEqual(Conf.get(index, 'key1'), 'val1') Conf.set(index, 'key2', 'val2') self.assertEqual(Conf.get_keys(index), ['key1', 'key2']) Conf.set(index, 'key2>key3>key4', 'val4') Conf.delete(index, 'key2>key3>key4') self.assertEqual(Conf.get(index, 'key2>key3>key4'), None)
def test_multilevel_changed_key_should_be_replaced_in_config(self): Conf.set("existing", "FOO", {"bar": "qux", "eggs": "ham"}) Conf.save("existing") Conf.set("new", "FOOBAR", {"baz": "spam", "eggs": "ham"}) Conf.delete("new", "FOO") Conf.set("new", "CHANGED[0]>FOO>bar", "FOOBAR>baz") Conf.save("new") conf_upgrade = ConfUpgrade(self.existing_config_url, self.new_config_url, self.merged_config_url) conf_upgrade.create_merged_config() Conf.load("merged", self.merged_config_url) self.assertIsNone(Conf.get("merged", "FOO")) self.assertIsNotNone(Conf.get("merged", "FOOBAR")) self.assertIsNotNone(Conf.get("merged", "FOOBAR>baz")) self.assertEqual(Conf.get("existing", "FOO>bar"), Conf.get("merged", "FOOBAR>baz"))
def delete(args): """ Deletes given set of keys from the config """ key_list = args.args[0].split(';') is_deleted = [] for key in key_list: status = Conf.delete(ConfCli._index, key) is_deleted.append(status) if any(is_deleted): Conf.save(ConfCli._index)
def test_conf_store_compare(self): """Test comparing given two index and return new/deleted/updated keys.""" load_config('conf1', 'json:///tmp/file1.json') load_config('conf2', 'json:///tmp/file2.json') Conf.delete('conf2', 'bridge>name') Conf.set('conf2', 'bridge>protocol', 'http') Conf.set('conf2', 'bridge>port', '51288') expected_new_keys = ['bridge>protocol'] expected_updated_keys = ['bridge>port'] actual_new_keys, actual_deleted_keys, actual_updated_keys = Conf.compare( 'conf1', 'conf2') self.assertEqual(actual_new_keys, expected_new_keys) self.assertEqual(actual_updated_keys, expected_updated_keys) self.assertTrue(True if 'bridge>name' in actual_deleted_keys else False) self.assertNotEqual(actual_new_keys, None) with self.assertRaises(ConfError): actual_new_keys, actual_deleted_keys, actual_updated_keys = Conf.compare( 'conf1', 'conf4')
def test_prepare_diff(self): """Test if changeset file is getting generated with new/changes/deleted keys""" Conf.load('index1', tmp_conf_url) Conf.load('index2', cortx_conf_url) # add 1 new key in tmp conf Conf.set('index1', 'cortx>common>name', 'CORTX') # Change previous key from tmp conf Conf.set('index1', 'cortx>common>security>device_certificate', '/etc/cortx/solution/security.pem') # Delete one key from tmp conf Conf.delete('index1', 'cortx>common>security>domain_certificate') Conf.save('index1') rc = 0 try: CortxProvisioner._prepare_diff('index2', 'index1', 'index3') except Exception as e: print('Exception: ', e) sys.stderr.write("%s\n" % traceback.format_exc()) rc = 1 self.assertEqual(rc, 0) self.assertEqual(Conf.get('index3', 'new>cortx>common>name'), 'CORTX')
def test_delete(self): Conf.load('test_file_1', 'yaml:///tmp/test_file_1.yaml') Conf.set('test_file_1', 'a>b>c>d', 'value1') Conf.set('test_file_1', 'a1>b>c>d[0]', 11) Conf.set('test_file_1', 'a1>b>c>d[1]', 22) # Deleting non leaf keys raise KvError with self.assertRaises(KvError): Conf.delete('test_file_1', 'a1>b>c>d') with self.assertRaises(KvError): Conf.delete('test_file_1', 'a>b>c') with self.assertRaises(KvError): Conf.delete('test_file_1', 'a') # Delete leaf node self.assertEqual(True, Conf.delete('test_file_1', 'a>b>c>d')) # Deleting empty intermediate key self.assertEqual(True, Conf.delete('test_file_1', 'a>b>c')) # Delete non leaf key with force: self.assertEqual(True, Conf.delete('test_file_1', 'a', True)) # Delete indexed key self.assertEqual(True, Conf.delete('test_file_1', 'a1>b>c>d[0]'))
def test_conf_store_ini(self): # basic set / set Conf.load('ini_1', 'ini:///tmp/file1.ini') Conf.set('ini_1', 'A>A1', '1') Conf.save('ini_1') # multi level key not supported by INI with self.assertRaises(KvError): Conf.set('ini_1', 'A>A1>A2', '1') # Check if operations reflected in file Conf.load('ini_2', 'ini:///tmp/file1.ini') with self.assertRaises(KvError): Conf.get('ini_2', 'A>A1>A2') self.assertEqual(Conf.get('ini_2', 'A>A1'), '1') Conf.delete('ini_2', 'A>A1') self.assertEqual(Conf.get('ini_2', 'A>A1'), None) self.assertEqual(Conf.get('ini_2', 'FOO>BAR'), None) # Confirm delete only reflected in memory Conf.load('ini_3', 'ini:///tmp/file1.ini') self.assertEqual(Conf.get('ini_2', 'A>A1'), '1') # Test copy function Conf.load('ini_4', 'ini:///tmp/file2.ini') Conf.copy('ini_3', 'ini_4') self.assertEqual(Conf.get('ini_4', 'A>A1'), '1') with self.assertRaises(KvError): Conf.get('ini_4', 'A>A1>A2') Conf.save('ini_4') # Test key case sensitivity Conf.set('ini_3', 'A>A1', '1') Conf.set('ini_3', 'a>a1', '2') self.assertNotEqual(Conf.get('ini_3', 'A>A1'), Conf.get('ini_3', 'A>a1'))
def test_006_conf_dictkvstore_delete_single_key(self): """Test conf store delete kv.""" Conf.delete('dict', 'k1') out = Conf.get('dict', 'k1') self.assertNotIn('k1', Conf.get_keys('dict')) self.assertIsNone(out)
def delete(args): """ Delete given set of keys from the config """ key_list = args.args[0].split(';') for key in key_list: Conf.delete(ConfCli._index, key) Conf.save(ConfCli._index)
def test_conf_store_delte_and_get(self): """ Test by removing the key, value from the given index. """ Conf.delete('pro_local', 'studio_location') result_data = Conf.get('pro_local', 'studio_location') self.assertEqual(result_data, None)
def test_conf_store_delete_with_index(self): """ Test by removing the key, value from the given index. """ load_config('delete_local_index', 'json:///tmp/file1.json') Conf.delete('delete_local_index', 'bridge>lte_type[1]') result_data = Conf.get('delete_local_index', 'bridge>lte_type[1]>name') self.assertEqual(result_data, None)
def test_007_conf_dictkvstore_delete_nested_key(self): """Test conf store delete nested kv.""" Conf.delete('dict', 'k2>k4>k6>k7') out = Conf.get('dict', 'k2>k4>k6>k7') self.assertNotIn('k2>k4>k6>k7', Conf.get_keys('dict')) self.assertIsNone(out)
def test_008_conf_dictkvstore_delete_nonexistent_key(self): """Test conf store delete non-existent kv.""" delete_out = Conf.delete('dict', 'k2>k4>k6>k7>k11>k12') self.assertFalse(delete_out)
def delete_key(self, key: str, save: bool = False): """Deletes the specified key.""" Conf.delete(self.default_index, key) if save == True: # Update the index backend. Conf.save(self.default_index)