def test_install_import_configs(self): """Test the install function with imported configs""" # dotpath location tmp = get_tempdir() self.assertTrue(os.path.exists(tmp)) self.addCleanup(clean, tmp) os.mkdir(os.path.join(tmp, 'importing')) os.mkdir(os.path.join(tmp, 'imported')) # where dotfiles will be installed dst = get_tempdir() self.assertTrue(os.path.exists(dst)) self.addCleanup(clean, dst) # creating random dotfiles imported_dotfile, _ = create_random_file(os.path.join(tmp, 'imported')) imported_dotfile = { 'dst': os.path.join(dst, imported_dotfile), 'key': 'f_{}'.format(imported_dotfile), 'name': imported_dotfile, 'src': os.path.join(tmp, 'imported', imported_dotfile), } importing_dotfile, _ = \ create_random_file(os.path.join(tmp, 'importing')) importing_dotfile = { 'dst': os.path.join(dst, importing_dotfile), 'key': 'f_{}'.format(importing_dotfile), 'name': importing_dotfile, 'src': os.path.join(tmp, 'imported', importing_dotfile), } imported = { 'config': { 'dotpath': 'imported', }, 'dotfiles': { imported_dotfile['key']: { 'dst': imported_dotfile['dst'], 'src': imported_dotfile['name'], }, }, 'profiles': { 'host1': { 'dotfiles': [imported_dotfile['key']], }, }, } importing = { 'config': { 'dotpath': 'importing', }, 'dotfiles': { importing_dotfile['key']: { 'dst': importing_dotfile['dst'], 'src': importing_dotfile['src'], }, }, 'profiles': { 'host2': { 'dotfiles': [importing_dotfile['key']], 'include': ['host1'], }, }, } # create the imported base config file imported_path = create_fake_config(tmp, configname='config-2.yaml', **imported['config']) # create the importing base config file importing_path = create_fake_config(tmp, configname='config.yaml', import_configs=['config-2.yaml'], **importing['config']) # edit the imported config populate_fake_config(imported_path, **{ k: v for k, v in imported.items() if k != 'config' }) # edit the importing config populate_fake_config(importing_path, **{ k: v for k, v in importing.items() if k != 'config' }) # install them o = load_options(importing_path, 'host2') o.safe = False o.install_showdiff = True o.variables = {} cmd_install(o) # now compare the generated files self.assertTrue(os.path.exists(importing_dotfile['dst'])) self.assertTrue(os.path.exists(imported_dotfile['dst']))
def test_import_configs_override(self): """Test import_configs when some config keys overlap.""" tmp = get_tempdir() self.assertTrue(os.path.exists(tmp)) self.addCleanup(clean, tmp) vars_ed = { 'variables': { 'a_var': '33', }, 'dynvariables': { 'a_dynvar': 'echo 33', }, } vars_ing = { 'variables': { 'a_var': 'dd', }, 'dynvariables': { 'a_dynvar': 'echo dd', }, } vars_ed_file = create_yaml_keyval(vars_ed, tmp) vars_ing_file = create_yaml_keyval(vars_ing, tmp) actions_ed = { 'actions': { 'pre': { 'a_pre_action': 'echo pre 22', }, 'post': { 'a_post_action': 'echo post 22', }, 'a_action': 'echo 22', } } actions_ing = { 'actions': { 'pre': { 'a_pre_action': 'echo pre aa', }, 'post': { 'a_post_action': 'echo post aa', }, 'a_action': 'echo aa', } } actions_ed_file = create_yaml_keyval(actions_ed, tmp) actions_ing_file = create_yaml_keyval(actions_ing, tmp) imported = { 'config': { 'dotpath': 'imported', 'backup': False, 'import_variables': [vars_ed_file], 'import_actions': [actions_ed_file], }, 'dotfiles': { 'f_vimrc': { 'dst': '~/.vimrc', 'src': 'vimrc' }, 'f_xinitrc': { 'dst': '~/.xinitrc', 'src': 'xinitrc', 'link': 'link' }, }, 'profiles': { 'host1': { 'dotfiles': ['f_vimrc'], }, 'host2': { 'dotfiles': ['f_xinitrc'], }, }, 'actions': { 'pre': { 'a_pre_log': 'echo pre 2', }, 'post': { 'a_post_log': 'echo post 2', }, 'a_log': 'echo 2', }, 'trans': { 't_log': 'echo 3', }, 'trans_write': { 'tw_log': 'echo 4', }, 'variables': { 'v_log': '42', }, 'dynvariables': { 'dv_log': 'echo 5', }, } importing = { 'config': { 'dotpath': 'importing', 'backup': True, 'import_variables': [vars_ing_file], 'import_actions': [actions_ing_file], }, 'dotfiles': { 'f_xinitrc': { 'dst': '~/.xinitrc', 'src': 'xinitrc' }, }, 'profiles': { 'host2': { 'dotfiles': ['f_xinitrc'], 'include': ['host1'], }, }, 'actions': { 'pre': { 'a_pre_log': 'echo pre a', }, 'post': { 'a_post_log': 'echo post a', }, 'a_log': 'echo a', }, 'trans': { 't_log': 'echo b', }, 'trans_write': { 'tw_log': 'echo c', }, 'variables': { 'v_log': 'd', }, 'dynvariables': { 'dv_log': 'echo e', }, } # create the imported base config file imported_path = create_fake_config(tmp, configname=self.CONFIG_NAME_2, **imported['config']) # create the importing base config file importing_path = create_fake_config(tmp, configname=self.CONFIG_NAME, import_configs=(imported_path, ), **importing['config']) # edit the imported config populate_fake_config( imported_path, **{k: v for k, v in imported.items() if k != 'config'}) # edit the importing config populate_fake_config( importing_path, **{k: v for k, v in importing.items() if k != 'config'}) # do the tests importing_cfg = Cfg(importing_path, debug=True) imported_cfg = Cfg(imported_path, debug=True) self.assertIsNotNone(importing_cfg) self.assertIsNotNone(imported_cfg) # test profiles self.assertIsSubset(imported_cfg.profiles, importing_cfg.profiles) # test dotfiles self.assertEqual(importing_cfg.dotfiles['f_vimrc'], imported_cfg.dotfiles['f_vimrc']) self.assertNotEqual(importing_cfg.dotfiles['f_xinitrc'], imported_cfg.dotfiles['f_xinitrc']) # test actions self.assertFalse( any((imported_cfg.actions[key] == importing_cfg.actions[key]) for key in imported_cfg.actions)) # test transactions self.assertFalse( any(imported_cfg.trans_r[key] == importing_cfg.trans_r[key] for key in imported_cfg.trans_r)) self.assertFalse( any(imported_cfg.trans_w[key] == importing_cfg.trans_w[key] for key in imported_cfg.trans_w)) # test variables # since variables get merged they are # the same in both configs imported_vars = imported_cfg.variables self.assertFalse( any(imported_vars[k] != v for k, v in importing_cfg.variables.items() if not k.startswith('_'))) # test profiles dotfiles self.assertEqual(imported_cfg.profiles['host1']['dotfiles'], importing_cfg.profiles['host1']['dotfiles']) self.assertNotEqual(imported_cfg.profiles['host2']['dotfiles'], importing_cfg.profiles['host2']['dotfiles']) self.assertTrue( set(imported_cfg.profiles['host1']['dotfiles']) < set( importing_cfg.profiles['host2']['dotfiles']))
def test_ext_config_yaml_not_mix(self): """Test whether the import_configs mixes yaml files upon importing.""" # dotfiles on filesystem src = get_tempdir() self.assertTrue(os.path.exists(src)) self.addCleanup(clean, src) # create some random dotfiles dotfiles = [] for _ in range(3): dotfile, _ = create_random_file(src) dotfiles.append(dotfile) self.addCleanup(clean, dotfile) self.assertTrue(all(map(os.path.exists, dotfiles))) # create dotdrop home dotdrop_home = get_tempdir() self.assertTrue(os.path.exists(dotdrop_home)) self.addCleanup(clean, dotdrop_home) dotpath_ed = 'imported' imported = { 'config': { 'dotpath': dotpath_ed, }, 'dotfiles': {}, 'profiles': { 'host1': { 'dotfiles': [], }, }, 'actions': { 'pre': { 'a_pre_log_ed': 'echo pre 2', }, 'post': { 'a_post_log_ed': 'echo post 2', }, 'a_log_ed': 'echo 2', }, 'trans': { 't_log_ed': 'echo 3', }, 'trans_write': { 'tw_log_ed': 'echo 4', }, 'variables': { 'v_log_ed': '42', }, 'dynvariables': { 'dv_log_ed': 'echo 5', }, } dotpath_ing = 'importing' importing = { 'config': { 'dotpath': dotpath_ing, }, 'dotfiles': {}, 'profiles': { 'host2': { 'dotfiles': [], 'include': ['host1'], }, }, 'actions': { 'pre': { 'a_pre_log_ing': 'echo pre a', }, 'post': { 'a_post_log_ing': 'echo post a', }, 'a_log_ing': 'echo a', }, 'trans': { 't_log_ing': 'echo b', }, 'trans_write': { 'tw_log_ing': 'echo c', }, 'variables': { 'v_log_ing': 'd', }, 'dynvariables': { 'dv_log_ing': 'echo e', }, } dotfiles_ing, dotfiles_ed = dotfiles[:-1], dotfiles[-1:] # create the imported base config file imported_path = create_fake_config(dotdrop_home, configname='config-2.yaml', **imported['config']) # create the importing base config file importing_path = create_fake_config(dotdrop_home, configname='config.yaml', import_configs=['config-2.yaml'], **importing['config']) # edit the imported config populate_fake_config( imported_path, **{k: v for k, v in imported.items() if k != 'config'}) # edit the importing config populate_fake_config( importing_path, **{k: v for k, v in importing.items() if k != 'config'}) # import the dotfiles o = load_options(imported_path, 'host1') o.import_path = dotfiles_ed cmd_importer(o) o = load_options(importing_path, 'host2') o.import_path = dotfiles_ing cmd_importer(o) # reload the config o = load_options(importing_path, 'host2') # test imported config y = self.load_yaml(imported_path) # testing dotfiles self.assertTrue(all(file_in_yaml(y, df) for df in dotfiles_ed)) self.assertFalse(any(file_in_yaml(y, df) for df in dotfiles_ing)) # testing profiles profiles = y['profiles'].keys() self.assertTrue('host1' in profiles) self.assertFalse('host2' in profiles) # testing actions actions = y['actions']['pre'] actions.update(y['actions']['post']) actions.update({ k: v for k, v in y['actions'].items() if k not in ('pre', 'post') }) actions = actions.keys() self.assertTrue(all(a.endswith('ed') for a in actions)) self.assertFalse(any(a.endswith('ing') for a in actions)) # testing transformations transformations = y['trans_read'].keys() self.assertTrue(all(t.endswith('ed') for t in transformations)) self.assertFalse(any(t.endswith('ing') for t in transformations)) transformations = y['trans_write'].keys() self.assertTrue(all(t.endswith('ed') for t in transformations)) self.assertFalse(any(t.endswith('ing') for t in transformations)) # testing variables variables = self._remove_priv_vars(y['variables'].keys()) self.assertTrue(all(v.endswith('ed') for v in variables)) self.assertFalse(any(v.endswith('ing') for v in variables)) dyn_variables = y['dynvariables'].keys() self.assertTrue(all(dv.endswith('ed') for dv in dyn_variables)) self.assertFalse(any(dv.endswith('ing') for dv in dyn_variables)) # test importing config y = self.load_yaml(importing_path) # testing dotfiles self.assertTrue(all(file_in_yaml(y, df) for df in dotfiles_ing)) self.assertFalse(any(file_in_yaml(y, df) for df in dotfiles_ed)) # testing profiles profiles = y['profiles'].keys() self.assertTrue('host2' in profiles) self.assertFalse('host1' in profiles) # testing actions actions = y['actions']['pre'] actions.update(y['actions']['post']) actions.update({ k: v for k, v in y['actions'].items() if k not in ('pre', 'post') }) actions = actions.keys() self.assertTrue(all(action.endswith('ing') for action in actions)) self.assertFalse(any(action.endswith('ed') for action in actions)) # testing transformations transformations = y['trans_read'].keys() self.assertTrue(all(t.endswith('ing') for t in transformations)) self.assertFalse(any(t.endswith('ed') for t in transformations)) transformations = y['trans_write'].keys() self.assertTrue(all(t.endswith('ing') for t in transformations)) self.assertFalse(any(t.endswith('ed') for t in transformations)) # testing variables variables = self._remove_priv_vars(y['variables'].keys()) self.assertTrue(all(v.endswith('ing') for v in variables)) self.assertFalse(any(v.endswith('ed') for v in variables)) dyn_variables = y['dynvariables'].keys() self.assertTrue(all(dv.endswith('ing') for dv in dyn_variables)) self.assertFalse(any(dv.endswith('ed') for dv in dyn_variables))
def test_import_configs_merge(self): """Test import_configs when all config keys merge.""" tmp = get_tempdir() self.assertTrue(os.path.exists(tmp)) self.addCleanup(clean, tmp) vars_ed = { 'variables': { 'a_var_ed': '33', }, 'dynvariables': { 'a_dynvar_ed': 'echo 33', }, } vars_ing = { 'variables': { 'a_var_ing': 'dd', }, 'dynvariables': { 'a_dynvar_ing': 'echo dd', }, } vars_ed_file = create_yaml_keyval(vars_ed, tmp) vars_ing_file = create_yaml_keyval(vars_ing, tmp) actions_ed = { 'actions': { 'pre': { 'a_pre_action_ed': 'echo pre 22', }, 'post': { 'a_post_action_ed': 'echo post 22', }, 'a_action_ed': 'echo 22', } } actions_ing = { 'actions': { 'pre': { 'a_pre_action_ing': 'echo pre aa', }, 'post': { 'a_post_action_ing': 'echo post aa', }, 'a_action_ing': 'echo aa', } } actions_ed_file = create_yaml_keyval(actions_ed, tmp) actions_ing_file = create_yaml_keyval(actions_ing, tmp) imported = { 'config': { 'dotpath': 'importing', 'import_variables': [vars_ed_file], 'import_actions': [actions_ed_file], }, 'dotfiles': { 'f_vimrc': { 'dst': '~/.vimrc', 'src': 'vimrc' }, }, 'profiles': { 'host1': { 'dotfiles': ['f_vimrc'], }, }, 'actions': { 'pre': { 'a_pre_log_ed': 'echo pre 2', }, 'post': { 'a_post_log_ed': 'echo post 2', }, 'a_log_ed': 'echo 2', }, 'trans': { 't_log_ed': 'echo 3', }, 'trans_write': { 'tw_log_ed': 'echo 4', }, 'variables': { 'v_log_ed': '42', }, 'dynvariables': { 'dv_log_ed': 'echo 5', }, } importing = { 'config': { 'dotpath': 'importing', 'import_variables': [vars_ing_file], 'import_actions': [actions_ing_file], }, 'dotfiles': { 'f_xinitrc': { 'dst': '~/.xinitrc', 'src': 'xinitrc' }, }, 'profiles': { 'host2': { 'dotfiles': ['f_xinitrc'], 'include': ['host1'], }, }, 'actions': { 'pre': { 'a_pre_log_ing': 'echo pre a', }, 'post': { 'a_post_log_ing': 'echo post a', }, 'a_log_ing': 'echo a', }, 'trans': { 't_log_ing': 'echo b', }, 'trans_write': { 'tw_log_ing': 'echo c', }, 'variables': { 'v_log_ing': 'd', }, 'dynvariables': { 'dv_log_ing': 'echo e', }, } # create the imported base config file imported_path = create_fake_config(tmp, configname=self.CONFIG_NAME_2, **imported['config']) # create the importing base config file importing_path = create_fake_config( tmp, configname=self.CONFIG_NAME, import_configs=[self.CONFIG_NAME_2], **importing['config']) # edit the imported config populate_fake_config( imported_path, **{k: v for k, v in imported.items() if k != 'config'}) # edit the importing config populate_fake_config( importing_path, **{k: v for k, v in importing.items() if k != 'config'}) # do the tests importing_cfg = Cfg(importing_path, debug=True) imported_cfg = Cfg(imported_path, debug=True) self.assertIsNotNone(importing_cfg) self.assertIsNotNone(imported_cfg) # test profiles self.assertIsSubset(imported_cfg.profiles, importing_cfg.profiles) # test dotfiles self.assertIsSubset(imported_cfg.dotfiles, importing_cfg.dotfiles) # test actions pre_ed = post_ed = pre_ing = post_ing = {} for k, v in imported_cfg.actions.items(): kind, _ = v if kind == 'pre': pre_ed[k] = v elif kind == 'post': post_ed[k] = v for k, v in importing_cfg.actions.items(): kind, _ = v if kind == 'pre': pre_ing[k] = v elif kind == 'post': post_ing[k] = v self.assertIsSubset(pre_ed, pre_ing) self.assertIsSubset(post_ed, post_ing) # test transactions self.assertIsSubset(imported_cfg.trans_r, importing_cfg.trans_r) self.assertIsSubset(imported_cfg.trans_w, importing_cfg.trans_w) # test variables imported_vars = { k: v for k, v in imported_cfg.variables.items() if not k.startswith('_') } importing_vars = { k: v for k, v in importing_cfg.variables.items() if not k.startswith('_') } self.assertIsSubset(imported_vars, importing_vars) # test prodots self.assertIsSubset(imported_cfg.profiles, importing_cfg.profiles)