From bec39bf7d8923b15c26a4ba07491b4ebdea6391d Mon Sep 17 00:00:00 2001 From: Aleksey Maksimov Date: Sat, 24 May 2014 23:08:03 +0800 Subject: [PATCH] Fix for issue #280 Properly pass job parameters via json When files parameter present select correct job invokation url --- jenkinsapi/job.py | 34 +++++++++------ jenkinsapi_tests/systests/job_configs.py | 42 +++++++++++++++++++ .../systests/test_parameterized_builds.py | 22 ++++++++++ 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/jenkinsapi/job.py b/jenkinsapi/job.py index e468995..fb379d7 100644 --- a/jenkinsapi/job.py +++ b/jenkinsapi/job.py @@ -138,27 +138,29 @@ class Job(JenkinsBase, MutableJenkinsThing): return "%s/buildWithParameters" % self.baseurl @staticmethod - def _mk_json_from_build_parameters(build_params): + def _mk_json_from_build_parameters(build_params, file_params=None): """ - Build parameters must be submitted in a particular format - Key-Value pairs would be - far too simple, no no! Watch and read on and behold! + Build parameters must be submitted in a particular format + Key-Value pairs would be far too simple, no no! + Watch and read on and behold! """ assert isinstance( build_params, dict), 'Build parameters must be a dict' - try: - it = build_params.iteritems() - except AttributeError: - # Python3 - it = build_params.items() + build_p = [{'name': k, 'value': v} + for k, v in build_params.iteritems()] + out = {'parameter': build_p} + if file_params: + file_p = [{'name': k, 'file': k} + for k in file_params.iterkeys()] + out['parameter'].extend(file_p) - return {'parameter': [ - {'name': k, 'value': v} for k, v in it - ]} + return out @staticmethod - def mk_json_from_build_parameters(build_params): - to_json_structure = Job._mk_json_from_build_parameters(build_params) + def mk_json_from_build_parameters(build_params, file_params=None): + to_json_structure = Job._mk_json_from_build_parameters(build_params, + file_params) return json.dumps(to_json_structure) def invoke(self, securitytoken=None, block=False, skip_if_running=False, invoke_pre_check_delay=3, @@ -196,6 +198,11 @@ class Job(JenkinsBase, MutableJenkinsThing): self.get_jenkins_obj())) url = self.get_build_triggerurl() + # If job has file parameters - it must be triggered + # using "/build", not by "/buildWithParameters" + # "/buildWithParameters" will ignore non-file parameters + if files: + url = "%s/build" % self.baseurl if cause: build_params['cause'] = cause @@ -203,6 +210,7 @@ class Job(JenkinsBase, MutableJenkinsThing): if securitytoken: params['token'] = securitytoken + build_params['json'] = self.mk_json_from_build_parameters(build_params, files) data = build_params response = self.jenkins.requester.post_and_confirm_status( diff --git a/jenkinsapi_tests/systests/job_configs.py b/jenkinsapi_tests/systests/job_configs.py index 1cf58a6..2f127a4 100644 --- a/jenkinsapi_tests/systests/job_configs.py +++ b/jenkinsapi_tests/systests/job_configs.py @@ -270,3 +270,45 @@ echo $B > b.txt """.strip() + +JOB_WITH_FILE_AND_PARAMS = """ + + + + + false + + + + + file.txt + + + + B + B, like buzzing B. + + + + + + + true + false + false + false + + false + + + cat file.txt;echo $B > file1.txt + + + + + * + false + + + +""".strip() diff --git a/jenkinsapi_tests/systests/test_parameterized_builds.py b/jenkinsapi_tests/systests/test_parameterized_builds.py index 2c69cfd..678ea33 100644 --- a/jenkinsapi_tests/systests/test_parameterized_builds.py +++ b/jenkinsapi_tests/systests/test_parameterized_builds.py @@ -14,6 +14,7 @@ except ImportError: from jenkinsapi_tests.systests.base import BaseSystemTest from jenkinsapi_tests.test_utils.random_strings import random_string from jenkinsapi_tests.systests.job_configs import JOB_WITH_FILE +from jenkinsapi_tests.systests.job_configs import JOB_WITH_FILE_AND_PARAMS from jenkinsapi_tests.systests.job_configs import JOB_WITH_PARAMETERS from jenkinsapi.custom_exceptions import WillNotBuild @@ -98,6 +99,27 @@ class TestParameterizedBuilds(BaseSystemTest): expected_msg = 'A build with these parameters is already queued.' self.assertEqual(str(na.exception), expected_msg) + def test_invoke_job_with_file_and_params(self): + file_data = random_string() + param_data = random_string() + param_file = StringIO(file_data) + + job_name = 'create_%s' % random_string() + job = self.jenkins.create_job(job_name, JOB_WITH_FILE_AND_PARAMS) + job.invoke(block=True, files={'file.txt': param_file}, + build_params={'B': param_data}) + + build = job.get_last_build() + while build.is_running(): + time.sleep(0.25) + + artifacts = build.get_artifact_dict() + self.assertIsInstance(artifacts, dict) + art_file = artifacts['file.txt'] + self.assertTrue(art_file.get_data().strip(), file_data) + art_param = artifacts['file1.txt'] + self.assertTrue(art_param.get_data().strip(), param_data) + if __name__ == '__main__': unittest.main() -- 2.34.1