def test_check_matrix_combinations(self, node, distro, selectors, expected): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') parsed_selectors = ms.parse_selectors(selectors) assert list(ms.check_matrix_combinations(node, distro, parsed_selectors)) == expected
def test_get_spec_group_item(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.get_spec_group_item('something_else', 'foo') == { 'spam': 'ham' } with pytest.raises(KeyError): ms.get_spec_group_item('something_else', 'nope')
def test_select_data_ok(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.select_data(['version=2.4', 'something_else=foo'], 'fedora-26-x86_64') == \ {'authoritative_source_url': 'some.url.fedoraproject.org', 'distro_specific_help': 'Some Fedora specific help', 'spam': 'ham', 'vendor': 'Fedora Project', 'version': '2.4'}
def test_get_all_combinations_complex(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') def comb_key(c): return (c['distro'], c['something_else'], c['version']) assert sorted(ms.get_all_combinations(), key=comb_key) == sorted([ {'distro': 'centos-7-x86_64.yaml', 'something_else': 'bar', 'version': '2.2'}, {'distro': 'centos-7-x86_64.yaml', 'something_else': 'bar', 'version': '2.4'}, {'distro': 'centos-7-x86_64.yaml', 'something_else': 'foo', 'version': '2.2'}, {'distro': 'centos-7-x86_64.yaml', 'something_else': 'foo', 'version': '2.4'}, {'distro': 'centos-7-x86_64.yaml', 'something_else': 'baz', 'version': '2.2'}, {'distro': 'centos-7-x86_64.yaml', 'something_else': 'baz', 'version': '2.4'}, {'distro': 'fedora-26-x86_64.yaml', 'something_else': 'bar', 'version': '2.2'}, {'distro': 'fedora-26-x86_64.yaml', 'something_else': 'bar', 'version': '2.4'}, {'distro': 'fedora-26-x86_64.yaml', 'something_else': 'foo', 'version': '2.4'}, {'distro': 'fedora-26-x86_64.yaml', 'something_else': 'baz', 'version': '2.2'}, {'distro': 'fedora-26-x86_64.yaml', 'something_else': 'baz', 'version': '2.4'}, {'distro': 'fedora-25-x86_64.yaml', 'something_else': 'bar', 'version': '2.2'}, {'distro': 'fedora-25-x86_64.yaml', 'something_else': 'foo', 'version': '2.2'}, {'distro': 'fedora-25-x86_64.yaml', 'something_else': 'foo', 'version': '2.4'}, {'distro': 'fedora-25-x86_64.yaml', 'something_else': 'baz', 'version': '2.2'}, {'distro': 'fedora-25-x86_64.yaml', 'something_else': 'baz', 'version': '2.4'}, ], key=comb_key)
def test_verify_selectors_ok(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.verify_selectors(['version=2.4', 'something_else=foo'], distro='fedora-26-x86_64') == (True, '')
def test_parse_selectors_nok(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') with pytest.raises(MultispecError): ms.parse_selectors(['foo bar'])
def test_distrofile2name(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert ms.distrofile2name( 'foo/bar/fedora-26-x86_64.yaml') == 'fedora-26-x86_64'
def test_has_spec_group_item(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.has_spec_group_item('something_else', 'foo') assert not ms.has_spec_group_item('something_else', 'nope')
def test_select_data_nok(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') with pytest.raises(MultispecError): ms.select_data(['version=2.4', 'something_else=foobar'], 'fedora-27-x86_64')
def test_from_path_nok(self): with pytest.raises(SystemExit): Multispec.from_path('.', 'nope')
def test_get_all_combinations_simple(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert list(ms.get_all_combinations()) == [{'distro': 'fedora-26-x86_64.yaml'}]
def test_get_all_combinations_simple(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert list(ms.get_all_combinations()) == [{ 'distro': 'fedora-26-x86_64.yaml' }]
def test_get_spec_group_item(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.get_spec_group_item('something_else', 'foo') == {'spam': 'ham'} with pytest.raises(KeyError): ms.get_spec_group_item('something_else', 'nope')
def test_get_spec_group(self): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.get_spec_group('version') == \ {'2.2': {'version': '2.2'}, '2.4': {'version': '2.4'}} with pytest.raises(KeyError): ms.get_spec_group('nope')
def test_from_path_ok(self, proj_dir, path): assert Multispec.from_path(proj_dir, path).raw_data == simplest
def test_verify_selectors_nok(self, selectors, distro, msg): ms = Multispec.from_path(ms_fixtures, 'complex.yaml') assert ms.verify_selectors(selectors, distro) == (False, msg)
def render(self, specfiles, multispec, multispec_selectors, template, config, cmd_cfg, output, confdirs=None, explicit_macros={}, max_passes=1): """ render single template """ config_path = [self.project.directory] + self.pm_cfg.get_path() sysconfig = load_config(config_path, config) if not confdirs: confdirs = [] for i in confdirs + [self.project.directory]: additional_vars = self.load_config_from_project(i) self.vars_fill_variables(additional_vars, sysconfig) # filter only interresting variables interresting_parts = ['macros'] additional_vars = { x: additional_vars[x] for x in interresting_parts if x in additional_vars} sysconfig = merge_yaml(sysconfig, additional_vars) self.project.abstract_setup_vars(sysconfig) self.project.inst_init(specfiles, template, sysconfig) projcfg = self.load_config_from_project(self.project.directory) if projcfg and 'name' in projcfg: sysconfig['name'] = projcfg['name'] self.vars_fill_variables(sysconfig) explicit_macros = {'macros': explicit_macros} self.vars_fill_variables(explicit_macros, sysconfig) sysconfig = merge_yaml(sysconfig, explicit_macros) # NOTE: This is soo ugly, sorry for that, in future we need to modify # PyYAML to let us specify callbacks, somehow. But for now, import # yaml right here to be able to add the constructors/representers # "locally". import yaml def _eval_node(loader, node): return str(eval(str(loader.construct_scalar(node)), { 'project': self.project, 'config': sysconfig, 'macros': sysconfig['macros'], })) yaml.add_constructor(u'!eval', _eval_node) spec = {} for specfile in specfiles or []: specfd = self.pm_spc.open_file( specfile, [self.project.directory], fail=True, ) if not specfd: fatal("Spec file {0} not found".format(specfile)) try: specdata = yaml.load(specfd) spec = merge_yaml(spec, specdata) except yaml.YAMLError as exc: fatal("Error in spec file: {0}".format(exc)) if multispec: try: mltspc = Multispec.from_path(self.project.directory, multispec) spec = merge_yaml( spec, mltspc.select_data(multispec_selectors, config)) except yaml.YAMLError as exc: fatal("Error in multispec file: {0}".format(exc)) except MultispecError as exc: fatal(str(exc)) try: tpl = self.project.tplgen.get_template(template) except jinja2.exceptions.TemplateNotFound as err: fatal("Can not find template {0}".format(err)) self.project.inst_finish(specfiles, template, sysconfig, spec) rendering_kwargs = { 'config': sysconfig, 'macros': sysconfig['macros'], 'm': sysconfig['macros'], 'container': {'name': 'docker'}, 'spec': spec, 'project': self.project, 'commands': Commands(cmd_cfg, sysconfig), 'env': os.environ, } self._recursive_render_spec( spec, max_passes=max_passes, **rendering_kwargs ) output.write(tpl.render(**rendering_kwargs).encode('utf-8'))
def test_distrofile2name(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert ms.distrofile2name('foo/bar/fedora-26-x86_64.yaml') == 'fedora-26-x86_64'
def render(self, specfiles, multispec, multispec_selectors, template, config, cmd_cfg, output, confdirs=None, explicit_macros={}, max_passes=1): """ render single template """ config_path = [self.project.directory] + self.pm_cfg.get_path() sysconfig = load_config(config_path, config) if not confdirs: confdirs = [] for i in confdirs + [self.project.directory]: additional_vars = self.load_config_from_project(i) self.vars_fill_variables(additional_vars, sysconfig) # filter only interresting variables interresting_parts = ['macros'] additional_vars = { x: additional_vars[x] for x in interresting_parts if x in additional_vars} sysconfig = merge_yaml(sysconfig, additional_vars) self.project.abstract_setup_vars(sysconfig) self.project.inst_init(specfiles, template, sysconfig) projcfg = self.load_config_from_project(self.project.directory) if projcfg and 'name' in projcfg: sysconfig['name'] = projcfg['name'] self.vars_fill_variables(sysconfig) explicit_macros = {'macros': explicit_macros} self.vars_fill_variables(explicit_macros, sysconfig) sysconfig = merge_yaml(sysconfig, explicit_macros) yaml = self._enhanced_yaml_module(sysconfig) spec = {} for specfile in specfiles or []: specfd = self.pm_spc.open_file( specfile, [self.project.directory], fail=True, ) if not specfd: fatal("Spec file {0} not found".format(specfile)) try: specdata = yaml.dg_load(specfd) spec = merge_yaml(spec, specdata) except yaml.YAMLError as exc: fatal("Error in spec file: {0}".format(exc)) if multispec: try: mltspc = Multispec.from_path(self.project.directory, multispec) spec = merge_yaml( spec, mltspc.select_data(multispec_selectors, config)) except yaml.YAMLError as exc: fatal("Error in multispec file: {0}".format(exc)) except MultispecError as exc: fatal(str(exc)) try: tpl = self.project.tplgen.get_template(template) except jinja2.exceptions.TemplateNotFound as err: fatal("Can not find template {0}".format(err)) self.project.inst_finish(specfiles, template, sysconfig, spec) rendering_kwargs = { 'config': sysconfig, 'macros': sysconfig['macros'], 'm': sysconfig['macros'], 'container': {'name': 'docker'}, 'spec': spec, 'project': self.project, 'commands': Commands(cmd_cfg, sysconfig), 'env': os.environ, } self._recursive_render_spec( spec, max_passes=max_passes, **rendering_kwargs ) output.write(tpl.render(**rendering_kwargs).encode('utf-8'))
def test_parse_selectors_ok(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert ms.parse_selectors(['foo=bar', 'spam=ham']) == { 'foo': 'bar', 'spam': 'ham' }
def render(self, specfiles, multispec, multispec_selectors, template, config, cmd_cfg, output, confdirs=None, explicit_macros={}, max_passes=1): """ render single template """ config_path = [self.project.directory] + self.pm_cfg.get_path() sysconfig = load_config(config_path, config) if not confdirs: confdirs = [] for i in confdirs + [self.project.directory]: additional_vars = self.load_config_from_project(i) self.vars_fill_variables(additional_vars, sysconfig) # filter only interresting variables interresting_parts = ['macros'] additional_vars = { x: additional_vars[x] for x in interresting_parts if x in additional_vars } sysconfig = merge_yaml(sysconfig, additional_vars) self.project.abstract_setup_vars(sysconfig) self.project.inst_init(specfiles, template, sysconfig) projcfg = self.load_config_from_project(self.project.directory) if projcfg and 'name' in projcfg: sysconfig['name'] = projcfg['name'] self.vars_fill_variables(sysconfig) explicit_macros = {'macros': explicit_macros} self.vars_fill_variables(explicit_macros, sysconfig) sysconfig = merge_yaml(sysconfig, explicit_macros) # NOTE: This is soo ugly, sorry for that, in future we need to modify # PyYAML to let us specify callbacks, somehow. But for now, import # yaml right here to be able to add the constructors/representers # "locally". import yaml def _eval_node(loader, node): return str( eval( str(loader.construct_scalar(node)), { 'project': self.project, 'config': sysconfig, 'macros': sysconfig['macros'], })) yaml.add_constructor(u'!eval', _eval_node) spec = {} for specfile in specfiles or []: specfd = self.pm_spc.open_file( specfile, [self.project.directory], fail=True, ) if not specfd: fatal("Spec file {0} not found".format(specfile)) try: specdata = yaml.load(specfd) spec = merge_yaml(spec, specdata) except yaml.YAMLError as exc: fatal("Error in spec file: {0}".format(exc)) if multispec: try: mltspc = Multispec.from_path(self.project.directory, multispec) spec = merge_yaml( spec, mltspc.select_data(multispec_selectors, config)) except yaml.YAMLError as exc: fatal("Error in multispec file: {0}".format(exc)) except MultispecError as exc: fatal(str(exc)) try: tpl = self.project.tplgen.get_template(template) except jinja2.exceptions.TemplateNotFound as err: fatal("Can not find template {0}".format(err)) self.project.inst_finish(specfiles, template, sysconfig, spec) rendering_kwargs = { 'config': sysconfig, 'macros': sysconfig['macros'], 'm': sysconfig['macros'], 'container': { 'name': 'docker' }, 'spec': spec, 'project': self.project, 'commands': Commands(cmd_cfg, sysconfig), 'env': os.environ, } self._recursive_render_spec(spec, max_passes=max_passes, **rendering_kwargs) output.write(tpl.render(**rendering_kwargs).encode('utf-8'))
def test_parse_selectors_ok(self): ms = Multispec.from_path(ms_fixtures, 'simplest.yaml') assert ms.parse_selectors(['foo=bar', 'spam=ham']) == {'foo': 'bar', 'spam': 'ham'}