class TestCaseTestJenkinsManager(base.BaseTestCase): def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['plugin1', 'plugin2']) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins_info', return_value=['p1', 'p2']) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = None self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['p1', 'p2']) def test_delete_managed(self): self.jjb_config.builder['plugins_info'] = [] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) with mock.patch.multiple('jenkins_jobs.builder.JenkinsManager', get_jobs=mock.DEFAULT, is_managed=mock.DEFAULT, delete_job=mock.DEFAULT) as patches: patches['get_jobs'].return_value = [{'name': 'job1'}, {'name': 'job2'}] patches['is_managed'].side_effect = [True, True] self.builder.delete_old_managed() self.assertEquals(patches['delete_job'].call_count, 2)
class TestCaseTestJenkinsManager(base.BaseTestCase): def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = _plugins_info self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, _plugins_info) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins', return_value=_plugins_info) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) # See https://github.com/formiaczek/multi_key_dict/issues/17 # self.assertEqual(self.builder.plugins_list, k) for key_tuple in self.builder.plugins_list.keys(): for key in key_tuple: self.assertEqual(self.builder.plugins_list[key], _plugins_info[key]) def test_delete_managed(self): self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) with mock.patch.multiple('jenkins_jobs.builder.JenkinsManager', get_jobs=mock.DEFAULT, is_managed=mock.DEFAULT, delete_job=mock.DEFAULT) as patches: patches['get_jobs'].return_value = [{ 'fullname': 'job1' }, { 'fullname': 'job2' }] patches['is_managed'].side_effect = [True, True] self.builder.delete_old_managed() self.assertEqual(patches['delete_job'].call_count, 2) def _get_plugins_info_error_test(self, error_string): builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) exception = jenkins_jobs.builder.jenkins.JenkinsException(error_string) with mock.patch.object(builder.jenkins, 'get_plugins', side_effect=exception): plugins_info = builder.get_plugins_info() self.assertEqual([_plugins_info['plugin1']], plugins_info) def test_get_plugins_info_handles_connectionrefused_errors(self): self._get_plugins_info_error_test('Connection refused') def test_get_plugins_info_handles_forbidden_errors(self): self._get_plugins_info_error_test('Forbidden')
class TestCaseTestJenkinsManager(base.BaseTestCase): def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = _plugins_info self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, _plugins_info) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins', return_value=_plugins_info) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) # See https://github.com/formiaczek/multi_key_dict/issues/17 # self.assertEqual(self.builder.plugins_list, k) for key_tuple in self.builder.plugins_list.keys(): for key in key_tuple: self.assertEqual(self.builder.plugins_list[key], _plugins_info[key]) def test_delete_managed(self): self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) with mock.patch.multiple('jenkins_jobs.builder.JenkinsManager', get_jobs=mock.DEFAULT, is_job=mock.DEFAULT, is_managed=mock.DEFAULT, delete_job=mock.DEFAULT) as patches: patches['get_jobs'].return_value = [{'fullname': 'job1'}, {'fullname': 'job2'}] patches['is_managed'].side_effect = [True, True] patches['is_job'].side_effect = [True, True] self.builder.delete_old_managed() self.assertEqual(patches['delete_job'].call_count, 2) def _get_plugins_info_error_test(self, error_string): builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) exception = jenkins_jobs.builder.jenkins.JenkinsException(error_string) with mock.patch.object(builder.jenkins, 'get_plugins', side_effect=exception): plugins_info = builder.get_plugins_info() self.assertEqual([_plugins_info['plugin1']], plugins_info) def test_get_plugins_info_handles_connectionrefused_errors(self): self._get_plugins_info_error_test('Connection refused') def test_get_plugins_info_handles_forbidden_errors(self): self._get_plugins_info_error_test('Forbidden')
def setUp(self): super(ModuleRegistryPluginInfoTestsWithScenarios, self).setUp() jjb_config = JJBConfig() jjb_config.validate() plugin_info = [{"shortName": "HerpDerpPlugin", "longName": "Blah Blah Blah Plugin"}] plugin_info.append({"shortName": "JankyPlugin1", "longName": "Not A Real Plugin", "version": self.v1}) self.addDetail("plugin_info", text_content(str(plugin_info))) self.registry = ModuleRegistry(jjb_config, plugin_info)
def test_retain_anchors_enabled(self): """ Verify that anchors are retained across files if retain_anchors is enabled in the config. """ files = ["custom_retain_anchors_include001.yaml", "custom_retain_anchors.yaml"] jjb_config = JJBConfig() jjb_config.yamlparser['retain_anchors'] = True jjb_config.validate() j = YamlParser(jjb_config) j.load_files([os.path.join(self.fixtures_path, f) for f in files])
def test_retain_anchors_default(self): """ Verify that anchors are NOT retained across files by default. """ files = ["custom_retain_anchors_include001.yaml", "custom_retain_anchors.yaml"] jjb_config = JJBConfig() # use the default value for retain_anchors jjb_config.validate() j = YamlParser(jjb_config) with ExpectedException(yaml.composer.ComposerError, "found undefined alias.*"): j.load_files([os.path.join(self.fixtures_path, f) for f in files])
def setUp(self): super(ModuleRegistryPluginInfoTestsWithScenarios, self).setUp() jjb_config = JJBConfig() jjb_config.validate() plugin_info = [{ "shortName": "HerpDerpPlugin", "longName": "Blah Blah Blah Plugin" }] plugin_info.append({ "shortName": "JankyPlugin1", "longName": "Not A Real Plugin", "version": self.v1, }) self.addDetail("plugin_info", text_content(str(plugin_info))) self.registry = ModuleRegistry(jjb_config, plugin_info)
class TestCaseTestBuilder(base.BaseTestCase): def setUp(self): super(TestCaseTestBuilder, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['plugin1', 'plugin2']) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins_info', return_value=['p1', 'p2']) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = None self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['p1', 'p2'])
def __init__(self, args=None, **kwargs): if args is None: args = [] self.parser = create_parser() self.options = self.parser.parse_args(args) self.jjb_config = JJBConfig(self.options.conf, **kwargs) if not self.options.command: self.parser.error("Must specify a 'command' to be performed") if (self.options.log_level is not None): self.options.log_level = getattr(logging, self.options.log_level.upper(), logger.getEffectiveLevel()) logger.setLevel(self.options.log_level) self._parse_additional() self.jjb_config.validate()
class TestCaseTestBuilder(LoggingFixture, TestCase): def setUp(self): super(TestCaseTestBuilder, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['plugin1', 'plugin2']) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins_info', return_value=['p1', 'p2']) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = None self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['p1', 'p2'])
def test_retain_anchors_enabled_j2_yaml(self): """ Verify that anchors are retained across files and are properly retained when using !j2-yaml. """ files = [ "custom_retain_anchors_j2_yaml_include001.yaml", "custom_retain_anchors_j2_yaml.yaml", ] jjb_config = JJBConfig() jjb_config.yamlparser["retain_anchors"] = True jjb_config.validate() j = YamlParser(jjb_config) j.load_files([os.path.join(self.fixtures_path, f) for f in files]) registry = ModuleRegistry(jjb_config, None) jobs, _ = j.expandYaml(registry) self.assertEqual(jobs[0]["builders"][0]["shell"], "docker run ubuntu:latest")
class TestCaseTestJenkinsManager(base.BaseTestCase): def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['plugin1', 'plugin2']) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins_info', return_value=['p1', 'p2']) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = None self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, ['p1', 'p2']) def test_delete_managed(self): self.jjb_config.builder['plugins_info'] = [] self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) with mock.patch.multiple('jenkins_jobs.builder.JenkinsManager', get_jobs=mock.DEFAULT, is_managed=mock.DEFAULT, delete_job=mock.DEFAULT) as patches: patches['get_jobs'].return_value = [{ 'name': 'job1' }, { 'name': 'job2' }] patches['is_managed'].side_effect = [True, True] self.builder.delete_old_managed() self.assertEquals(patches['delete_job'].call_count, 2)
def test_multiple_same_anchor_in_multiple_toplevel_yaml(self): """ Verify that anchors/aliases only span use of '!include' tag To ensure that any yaml loaded by the include tag is in the same space as the top level file, but individual top level yaml definitions are treated by the yaml loader as independent. """ files = ["custom_same_anchor-001-part1.yaml", "custom_same_anchor-001-part2.yaml"] jjb_config = JJBConfig() jjb_config.jenkins['url'] = 'http://example.com' jjb_config.jenkins['user'] = '******' jjb_config.jenkins['password'] = '******' jjb_config.builder['plugins_info'] = [] jjb_config.validate() j = YamlParser(jjb_config) j.load_files([os.path.join(self.fixtures_path, f) for f in files])
def assert_case(case_name): case_source, case_result = (os.path.join(BASE_PATH, case_name + ext) for ext in ['.yml', '.xml']) jjb_config = JJBConfig() builder = Builder(jjb_config) # Generate XML parser = YamlParser(jjb_config) registry = ModuleRegistry(jjb_config, builder.plugins_list) xml_generator = XmlJobGenerator(registry) parser.load_files(case_source) registry.set_parser_data(parser.data) job_data_list = parser.expandYaml(registry, []) xml_jobs = xml_generator.generateXML(job_data_list) result_xml = ET.XML(xml_jobs[0].output()) expected_xml = ET.XML(open(case_result).read()) assert ET.tostring(result_xml) == ET.tostring(expected_xml)
def _get_config(self): jjb_config = JJBConfig(self.conf_filename) jjb_config.validate() return jjb_config
class TestCaseTestJenkinsManager(base.BaseTestCase): def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate() def test_plugins_list(self): self.jjb_config.builder['plugins_info'] = _plugins_info self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.plugins_list, _plugins_info) @mock.patch('jenkins.Jenkins', side_effect=range(2)) def test_admin_user_defaulting(self, jenkins_mock): self.jjb_config.jenkins['user'] = '******' self.jjb_config.jenkins['password'] = '******' self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.jenkins, 0) # first call self.assertEqual(jenkins_mock.call_args_list[0][0][1:3], ('myuser', 'mypassword')) self.assertEqual(self.builder.admin_jenkins, 1) # second call self.assertEqual(jenkins_mock.call_args_list[1][0][1:3], ('myuser', 'mypassword')) @mock.patch('jenkins.Jenkins', side_effect=range(2)) def test_admin_user_specified(self, jenkins_mock): self.jjb_config.jenkins['user'] = '******' self.jjb_config.jenkins['password'] = '******' self.jjb_config.jenkins['admin_user'] = '******' self.jjb_config.jenkins['admin_password'] = '******' self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) self.assertEqual(self.builder.jenkins, 0) # first call self.assertEqual(jenkins_mock.call_args_list[0][0][1:3], ('myuser', 'mypassword')) self.assertEqual(self.builder.admin_jenkins, 1) # second call self.assertEqual(jenkins_mock.call_args_list[1][0][1:3], ('myadminuser', 'myadminpassword')) @mock.patch.object(jenkins_jobs.builder.jenkins.Jenkins, 'get_plugins', return_value=_plugins_info) def test_plugins_list_from_jenkins(self, jenkins_mock): # Trigger fetching the plugins from jenkins when accessing the property self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) # See https://github.com/formiaczek/multi_key_dict/issues/17 # self.assertEqual(self.builder.plugins_list, k) for key_tuple in self.builder.plugins_list.keys(): for key in key_tuple: self.assertEqual(self.builder.plugins_list[key], _plugins_info[key]) def test_delete_managed(self): self.jjb_config.builder['plugins_info'] = {} self.builder = jenkins_jobs.builder.JenkinsManager(self.jjb_config) with mock.patch.multiple('jenkins_jobs.builder.JenkinsManager', get_jobs=mock.DEFAULT, is_managed=mock.DEFAULT, delete_job=mock.DEFAULT) as patches: patches['get_jobs'].return_value = [{ 'name': 'job1' }, { 'name': 'job2' }] patches['is_managed'].side_effect = [True, True] self.builder.delete_old_managed() self.assertEquals(patches['delete_job'].call_count, 2)
class JenkinsJobs(object): """ This is the entry point class for the `jenkins-jobs` command line tool. While this class can be used programmatically by external users of the JJB API, the main goal here is to abstract the `jenkins_jobs` tool in a way that prevents test suites from caring overly much about various implementation details--for example, tests of subcommands must not have access to directly modify configuration objects, instead they must provide a fixture in the form of an .ini file that provides the configuration necessary for testing. External users of the JJB API may be interested in this class as an alternative to wrapping `jenkins_jobs` with a subprocess that execs it as a system command; instead, python scripts may be written that pass `jenkins_jobs` args directly to this class to allow programmatic setting of various command line parameters. """ def __init__(self, args=None, **kwargs): if args is None: args = [] self.parser = create_parser() self.options = self.parser.parse_args(args) self.jjb_config = JJBConfig(self.options.conf, config_section=self.options.section, **kwargs) if not self.options.command: self.parser.error("Must specify a 'command' to be performed") if (self.options.log_level is not None): self.options.log_level = getattr(logging, self.options.log_level.upper(), logger.getEffectiveLevel()) logger.setLevel(self.options.log_level) self._parse_additional() self.jjb_config.validate() def _set_config(self, target, option): """ Sets the option in target only if the given option was explicitly set """ opt_val = getattr(self.options, option, None) if opt_val is not None: target[option] = opt_val def _parse_additional(self): self._set_config(self.jjb_config.builder, 'ignore_cache') self._set_config(self.jjb_config.builder, 'flush_cache') self._set_config(self.jjb_config.yamlparser, 'allow_empty_variables') self._set_config(self.jjb_config.jenkins, 'section') self._set_config(self.jjb_config.jenkins, 'user') self._set_config(self.jjb_config.jenkins, 'password') if getattr(self.options, 'plugins_info_path', None) is not None: with io.open(self.options.plugins_info_path, 'r', encoding='utf-8') as yaml_file: plugins_info = yaml.load(yaml_file) if not isinstance(plugins_info, list): self.parser.error("{0} must contain a Yaml list!".format( self.options.plugins_info_path)) self.jjb_config.builder['plugins_info'] = plugins_info if getattr(self.options, 'path', None): if hasattr(self.options.path, 'read'): logger.debug("Input file is stdin") if self.options.path.isatty(): if platform.system() == 'Windows': key = 'CTRL+Z' else: key = 'CTRL+D' logger.warning("Reading configuration from STDIN. " "Press %s to end input.", key) self.options.path = [self.options.path] else: # take list of paths self.options.path = self.options.path.split(os.pathsep) do_recurse = (getattr(self.options, 'recursive', False) or self.jjb_config.recursive) excludes = ([e for elist in self.options.exclude for e in elist.split(os.pathsep)] or self.jjb_config.excludes) paths = [] for path in self.options.path: if do_recurse and os.path.isdir(path): paths.extend(utils.recurse_path(path, excludes)) else: paths.append(path) self.options.path = paths def execute(self): extension_manager = extension.ExtensionManager( namespace='jjb.cli.subcommands', invoke_on_load=True,) ext = extension_manager[self.options.command] ext.obj.execute(self.options, self.jjb_config)
def setUp(self): super(TestCaseTestJenkinsManager, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate()
def setUp(self): super(TestCaseTestBuilder, self).setUp() jjb_config = JJBConfig() jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] jjb_config.validate() self.builder = jenkins_jobs.builder.JenkinsManager(jjb_config)
class JenkinsJobs(object): """ This is the entry point class for the `jenkins-jobs` command line tool. While this class can be used programmatically by external users of the JJB API, the main goal here is to abstract the `jenkins_jobs` tool in a way that prevents test suites from caring overly much about various implementation details--for example, tests of subcommands must not have access to directly modify configuration objects, instead they must provide a fixture in the form of an .ini file that provides the configuration necessary for testing. External users of the JJB API may be interested in this class as an alternative to wrapping `jenkins_jobs` with a subprocess that execs it as a system command; instead, python scripts may be written that pass `jenkins_jobs` args directly to this class to allow programmatic setting of various command line parameters. """ def __init__(self, args=None, **kwargs): if args is None: args = [] self.parser = create_parser() self.options = self.parser.parse_args(args) self.jjb_config = JJBConfig(self.options.conf, **kwargs) if not self.options.command: self.parser.error("Must specify a 'command' to be performed") logger = logging.getLogger() if (self.options.log_level is not None): self.options.log_level = getattr(logging, self.options.log_level.upper(), logger.getEffectiveLevel()) logger.setLevel(self.options.log_level) self._parse_additional() self.jjb_config.validate() def _set_config(self, target, option): """ Sets the option in target only if the given option was explicitly set """ opt_val = getattr(self.options, option, None) if opt_val is not None: target[option] = opt_val def _parse_additional(self): self._set_config(self.jjb_config.builder, 'ignore_cache') self._set_config(self.jjb_config.builder, 'flush_cache') self._set_config(self.jjb_config.yamlparser, 'allow_empty_variables') self._set_config(self.jjb_config.jenkins, 'user') self._set_config(self.jjb_config.jenkins, 'password') if getattr(self.options, 'plugins_info_path', None) is not None: with io.open(self.options.plugins_info_path, 'r', encoding='utf-8') as yaml_file: plugins_info = yaml.load(yaml_file) if not isinstance(plugins_info, list): self.parser.error("{0} must contain a Yaml list!".format( self.options.plugins_info_path)) self.jjb_config.builder['plugins_info'] = plugins_info if getattr(self.options, 'path', None): if hasattr(self.options.path, 'read'): logger.debug("Input file is stdin") if self.options.path.isatty(): if platform.system() == 'Windows': key = 'CTRL+Z' else: key = 'CTRL+D' logger.warn("Reading configuration from STDIN. " "Press %s to end input.", key) else: # take list of paths self.options.path = self.options.path.split(os.pathsep) do_recurse = (getattr(self.options, 'recursive', False) or self.jjb_config.recursive) excludes = ([e for elist in self.options.exclude for e in elist.split(os.pathsep)] or self.jjb_config.excludes) paths = [] for path in self.options.path: if do_recurse and os.path.isdir(path): paths.extend(utils.recurse_path(path, excludes)) else: paths.append(path) self.options.path = paths def execute(self): options = self.options builder = Builder(self.jjb_config) if options.command == 'delete': for job in options.name: builder.delete_job(job, options.path) elif options.command == 'delete-all': if not utils.confirm( 'Sure you want to delete *ALL* jobs from Jenkins ' 'server?\n(including those not managed by Jenkins ' 'Job Builder)'): sys.exit('Aborted') logger.info("Deleting all jobs") builder.delete_all_jobs() elif options.command == 'update': if options.n_workers < 0: self.parser.error( 'Number of workers must be equal or greater than 0') logger.info("Updating jobs in {0} ({1})".format( options.path, options.names)) jobs, num_updated_jobs = builder.update_jobs( options.path, options.names, n_workers=options.n_workers) logger.info("Number of jobs updated: %d", num_updated_jobs) if options.delete_old: num_deleted_jobs = builder.delete_old_managed() logger.info("Number of jobs deleted: %d", num_deleted_jobs) elif options.command == 'test': builder.update_jobs(options.path, options.name, output=options.output_dir, n_workers=1)
def setUp(self): super(TestCaseTestBuilder, self).setUp() self.jjb_config = JJBConfig() self.jjb_config.validate()
class JenkinsJobs(object): """ This is the entry point class for the `jenkins-jobs` command line tool. While this class can be used programmatically by external users of the JJB API, the main goal here is to abstract the `jenkins_jobs` tool in a way that prevents test suites from caring overly much about various implementation details--for example, tests of subcommands must not have access to directly modify configuration objects, instead they must provide a fixture in the form of an .ini file that provides the configuration necessary for testing. External users of the JJB API may be interested in this class as an alternative to wrapping `jenkins_jobs` with a subprocess that execs it as a system command; instead, python scripts may be written that pass `jenkins_jobs` args directly to this class to allow programmatic setting of various command line parameters. """ def __init__(self, args=None, **kwargs): if args is None: args = [] self.parser = create_parser() self.options = self.parser.parse_args(args) self.jjb_config = JJBConfig(self.options.conf, config_section=self.options.section, **kwargs) if not self.options.command: self.parser.error("Must specify a 'command' to be performed") if (self.options.log_level is not None): self.options.log_level = getattr(logging, self.options.log_level.upper(), logger.getEffectiveLevel()) logger.setLevel(self.options.log_level) self._parse_additional() self.jjb_config.validate() def _set_config(self, target, option): """ Sets the option in target only if the given option was explicitly set """ opt_val = getattr(self.options, option, None) if opt_val is not None: target[option] = opt_val def _parse_additional(self): self._set_config(self.jjb_config.builder, 'ignore_cache') self._set_config(self.jjb_config.builder, 'flush_cache') self._set_config(self.jjb_config.builder, 'update') self._set_config(self.jjb_config.yamlparser, 'allow_empty_variables') self._set_config(self.jjb_config.jenkins, 'section') self._set_config(self.jjb_config.jenkins, 'user') self._set_config(self.jjb_config.jenkins, 'password') # Note: CLI options override config file options. if getattr(self.options, 'update', None) is None: self.options.update = self.jjb_config.builder.get('update') if self.options.update is None: self.options.update = 'all' if getattr(self.options, 'plugins_info_path', None) is not None: with io.open(self.options.plugins_info_path, 'r', encoding='utf-8') as yaml_file: plugins_info = yaml.load(yaml_file) if not isinstance(plugins_info, list): self.parser.error("{0} must contain a Yaml list!".format( self.options.plugins_info_path)) self.jjb_config.builder['plugins_info'] = plugins_info if getattr(self.options, 'path', None): if hasattr(self.options.path, 'read'): logger.debug("Input file is stdin") if self.options.path.isatty(): if platform.system() == 'Windows': key = 'CTRL+Z' else: key = 'CTRL+D' logger.warning( "Reading configuration from STDIN. " "Press %s to end input.", key) self.options.path = [self.options.path] else: # take list of paths self.options.path = self.options.path.split(os.pathsep) do_recurse = (getattr(self.options, 'recursive', False) or self.jjb_config.recursive) excludes = ([ e for elist in self.options.exclude for e in elist.split(os.pathsep) ] or self.jjb_config.excludes) paths = [] for path in self.options.path: if do_recurse and os.path.isdir(path): paths.extend(utils.recurse_path(path, excludes)) else: paths.append(path) self.options.path = paths def execute(self): extension_manager = extension.ExtensionManager( namespace='jjb.cli.subcommands', invoke_on_load=True, ) ext = extension_manager[self.options.command] ext.obj.execute(self.options, self.jjb_config)
def setUp(self): super(TestCaseTestBuilder, self).setUp() jjb_config = JJBConfig() jjb_config.builder['plugins_info'] = ['plugin1', 'plugin2'] jjb_config.validate() self.builder = jenkins_jobs.builder.Builder(jjb_config)