From 454b20e151740a4c87ccf800638fef4f96c7770c Mon Sep 17 00:00:00 2001 From: Panchorn Lertvipada Date: Thu, 28 Apr 2022 10:12:53 +0700 Subject: [PATCH 1/4] Add optional param ignore_exception for func build_jenkins_with_parameters_and_wait_until_job_done --- JenkinsLibrary/__init__.py | 2 +- JenkinsLibrary/jenkins_face.py | 21 ++- JenkinsLibrary/version.py | 2 +- README.md | 18 +- docs/JenkinsLibrary.html | 162 +++++++++++++++--- requirements.txt | 12 +- ...with_parameters_and_wait_until_job_done.py | 72 +++++++- 7 files changed, 240 insertions(+), 49 deletions(-) diff --git a/JenkinsLibrary/__init__.py b/JenkinsLibrary/__init__.py index 58f1aba..f8fd822 100644 --- a/JenkinsLibrary/__init__.py +++ b/JenkinsLibrary/__init__.py @@ -16,7 +16,7 @@ class JenkinsLibrary(JenkinsFace): | ${job_details}= | Get Jenkins Job | ${job_full_name} | | ${job_build_details}= | Get Jenkins Job Build | ${job_full_name} | ${build_number} | | ${build_number}= | Build Jenkins With Parameters | ${job_full_name} | ${parameters_string} | - | ${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | + | ${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | False | """ diff --git a/JenkinsLibrary/jenkins_face.py b/JenkinsLibrary/jenkins_face.py index bbf0cc1..352f81b 100644 --- a/JenkinsLibrary/jenkins_face.py +++ b/JenkinsLibrary/jenkins_face.py @@ -138,7 +138,14 @@ def build_jenkins_with_parameters(self, name=None, data=None): return job_detail['nextBuildNumber'] @keyword('Build Jenkins With Parameters And Wait Until Job Done') - def build_jenkins_with_parameters_and_wait_until_job_done(self, name=None, data=None, retry=24, retry_interval=5): + def build_jenkins_with_parameters_and_wait_until_job_done( + self, + name=None, + data=None, + retry=24, + retry_interval=5, + ignore_exception=True + ): """Build Jenkins With Parameters And Wait Until Job Done Trigger build job jenkins and wait until build job done @@ -148,11 +155,11 @@ def build_jenkins_with_parameters_and_wait_until_job_done(self, name=None, data= - data: job's parameters ``str`` - retry: number of times to retry ``int`` ``default is 24`` - retry_interval: time to wait before checking job status again ``int`` ``default is 5`` + - ignore_exception: flag to ignore an exception while waiting job done ``bool`` ``default is True`` Return dictionary of job information if job done ``dict``, otherwise will return ``None`` - Examples: - | ${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | + Examples: | ${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | False | """ if not name: raise Exception('Job name should not be None') @@ -161,15 +168,13 @@ def build_jenkins_with_parameters_and_wait_until_job_done(self, name=None, data= time.sleep(retry_interval) try: response = self.get_jenkins_job_build(name, next_build_no) - if response['building'] == False: + if not response['building']: return response - except requests.exceptions.HTTPError as err: - if err.response.status_code == 404: + except Exception as err: + if ignore_exception: pass else: raise err - except Exception as err: - raise err def _send(self, req): return self._session.send(req, **self._settings) diff --git a/JenkinsLibrary/version.py b/JenkinsLibrary/version.py index ddec2d2..004727f 100644 --- a/JenkinsLibrary/version.py +++ b/JenkinsLibrary/version.py @@ -1 +1 @@ -VERSION = '0.8.6' +VERSION = '0.8.7' diff --git a/README.md b/README.md index ff9ac7d..bda8e8a 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,15 @@ pip install -U robotframework-jenkinslibrary ``` ## Example Test Case -*** Settings *** | | | | | | ----------------------- |---------------------- |----------------- |---------------- |----------------- |----------------- | -Library | JenkinsLibrary | | | | | -*** Test Cases *** | | | | | | -create session jenkins | ${protocol} | ${host} | ${username} | ${password} | ${verify} | -${job_details}= | Get Jenkins Job | ${job_full_name} | | | | -${job_build_details}= | Get Jenkins Job Build | ${job_full_name} | ${build_number} | | | -${build_number}= | Build Jenkins With Parameters | ${job_full_name} | ${parameters_string} | | | -${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | +*** Settings *** | | | | | | | +---------------------- |---------------------- |----------------- |---------------- |----------------- |----------------- |----------------- | +Library | JenkinsLibrary | | | | | | +*** Test Cases *** | | | | | | | +create session jenkins | ${protocol} | ${host} | ${username} | ${password} | ${verify} | | +${job_details}= | Get Jenkins Job | ${job_full_name} | | | | | +${job_build_details}= | Get Jenkins Job Build | ${job_full_name} | ${build_number} | | | | +${build_number}= | Build Jenkins With Parameters | ${job_full_name} | ${parameters_string} | | | | +${job_build_details}= | Build Jenkins With Parameters And Wait Until Job Done | ${job_full_name} | ${parameters_string} | 10 | 2 | False | ## Document For more keyword detail go to the following link: diff --git a/docs/JenkinsLibrary.html b/docs/JenkinsLibrary.html index e112dff..9c7e9cd 100644 --- a/docs/JenkinsLibrary.html +++ b/docs/JenkinsLibrary.html @@ -5,7 +5,7 @@ - + + @@ -571,18 +638,26 @@

Opening library documentation failed

$(document).ready(function() { parseTemplates(); document.title = libdoc.name; + storage.init('libdoc'); renderTemplate('base', libdoc, $('body')); if (libdoc.inits.length) { renderTemplate('importing', libdoc); } renderTemplate('shortcuts', libdoc); + initShortcutListStyle('shortcut', libdoc.keywords); if (libdoc.contains_tags) { renderTemplate('tags', libdoc); + initShortcutListStyle('tag', libdoc.all_tags); } renderTemplate('keywords', libdoc); renderTemplate('footer', libdoc); + params = util.parseQueryString(window.location.search.slice(1)); + if ("tag" in params) { + tagSearch(params["tag"], window.location.hash); + } scrollToHash(); - $(document).bind('keydown', handleKeydown); + $(document).bind('keydown', handleKeyDown); + workaroundFirefoxWidthBug(); }); function parseTemplates() { @@ -602,7 +677,27 @@

Opening library documentation failed

$.tmpl(name + '-template', arguments).appendTo(container); } - function handleKeydown(event) { + function workaroundFirefoxWidthBug() { + // https://github.com/robotframework/robotframework/issues/3456 + // https://bugzilla.mozilla.org/show_bug.cgi?id=1613163 + $('.shortcuts a').width('max-content'); + } + + function initShortcutListStyle(name, items) { + var style = storage.get(name + '-list-style', 'compact'); + if (style != 'compact' && items.length > 1) { + $('.' + name + '-list-separator').html('
'); + $('.' + name + '-list-toggle .switch').prop('checked', true); + } + } + + function setShortcutListStyle(name) { + var compact = !$('.' + name + '-list-toggle .switch').prop('checked'); + $('.' + name + '-list-separator').html(compact ? '·' : '
'); + storage.set(name + '-list-style', compact ? 'compact' : 'expanded'); + } + + function handleKeyDown(event) { event = event || window.event; var keyCode = event.keyCode || event.which; if (keyCode === 27) // esc @@ -619,11 +714,14 @@

Opening library documentation failed

} } - function tagSearch(tag) { + function tagSearch(tag, hash) { var include = {tags: true, tagsExact: true}; + var url = window.location.pathname + "?tag=" + tag + (hash || ""); markMatches(tag, include); highlightMatches(tag, include); $('#keywords-container').find('.kw-row').addClass('hide-unmatched'); + history.replaceState && history.replaceState(null, '', url); + document.getElementById('Shortcuts').scrollIntoView(); } function doSearch() { @@ -693,6 +791,7 @@

Opening library documentation failed

$('#altogether-count').hide(); if (matchCount == 0) $('#keywords-container').find('table').empty(); + setTimeout(workaroundFirefoxWidthBug, 100); } function highlightMatches(string, include) { @@ -734,10 +833,7 @@

Opening library documentation failed

function resetSearch() { $('#search-string').val(''); - $('#include-name').prop('checked', true); - $('#include-args').prop('checked', true); - $('#include-doc').prop('checked', true); - $('#hide-unmatched').prop('checked', false); + $('#search input:checkbox').prop({'checked': true, 'disabled': false}); resetKeywords(); } @@ -749,6 +845,9 @@

Opening library documentation failed

} $('#match-count').hide(); $('#altogether-count').show(); + history.replaceState && history.replaceState(null, '', location.pathname + location.hash); + setTimeout(workaroundFirefoxWidthBug, 100); + scrollToHash(); } function setMatchVisibility() { @@ -825,7 +924,7 @@

Importing

{{each args}} - ${$value}{{if $index < args.length-1}}, {{/if}} + ${$value}{{if $index < args.length-1}},
{{/if}} {{/each}} {{html $value.doc}} @@ -836,25 +935,48 @@

Importing

@@ -883,14 +1005,14 @@

Keywords

{{each args}} - ${$value}{{if $index < args.length-1}}, {{/if}} + ${$value}{{if $index < args.length-1}},
{{/if}} {{/each}} {{if libdoc.contains_tags}} {{each tags}} ${$value}{{if $index < tags.length-1}}, {{/if}} + title="Show keywords with this tag">${$value}{{if $index < tags.length-1}},
{{/if}} {{/each}} {{/if}} diff --git a/requirements.txt b/requirements.txt index b682c21..3c464f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -requests -robotframework -pytest -pytest-cov -codecov -requests_mock \ No newline at end of file +requests==2.26.0 +robotframework==3.2.2 +pytest==6.2.4 +pytest-cov==2.12.1 +codecov==2.1.12 +requests_mock==1.9.3 \ No newline at end of file diff --git a/tests/test_build_jenkins_with_parameters_and_wait_until_job_done.py b/tests/test_build_jenkins_with_parameters_and_wait_until_job_done.py index 534a3a1..e00489b 100644 --- a/tests/test_build_jenkins_with_parameters_and_wait_until_job_done.py +++ b/tests/test_build_jenkins_with_parameters_and_wait_until_job_done.py @@ -95,9 +95,65 @@ def test_build_jenkins_with_parameters_and_wait_until_job_done_success(self, moc 'folder_name/test_job', 'data_test', retry=5, - retry_interval=1) + retry_interval=1 + ) self.assertEqual(job_build_details['nextBuildNumber'], 2) + @requests_mock.Mocker() + def test_build_jenkins_with_parameters_and_wait_until_job_done_when_http_exception_but_ignore_exception(self, mock): + mock.get( + 'http://username:password@localhost:8080/job/folder_name/job/test_job/api/json', + json={ + "_class": "", + "actions": [], + "description": None, + "displayName": "", + "displayNameOrNull": "", + "name": "", + "url": "http://localhost:8080/job/folder_name/job/test_job/", + "buildable": True, + "builds": [], + "color": "blue", + "firstBuild": {}, + "healthReport": [], + "inQueue": False, + "keepDependencies": False, + "lastBuild": {}, + "lastCompletedBuild": {}, + "lastFailedBuild": {}, + "lastStableBuild": {}, + "lastSuccessfulBuild": {}, + "lastUnstableBuild": None, + "lastUnsuccessfulBuild": {}, + "nextBuildNumber": 6, + "property": [], + "queueItem": None, + "concurrentBuild": False, + "building": True + } + ) + + mock.post( + 'http://username:password@localhost:8080/job/folder_name/job/test_job/buildWithParameters', + status_code=200 + ) + + mock.get( + 'http://username:password@localhost:8080/job/folder_name/job/test_job/6/api/json', + status_code=500 + ) + + self.jenkins.create_session_jenkins('http', 'localhost:8080', 'username', 'password', False) + + job_build_details = self.jenkins.build_jenkins_with_parameters_and_wait_until_job_done( + 'folder_name/test_job', + 'data_test', + retry=1, + retry_interval=1, + ignore_exception=True + ) + self.assertEqual(job_build_details, None) + def test_build_jenkins_with_parameters_and_wait_until_job_done_fail_when_name_is_none(self): self.jenkins.create_session_jenkins('http', 'localhost:8080', 'username', 'password', False) try: @@ -159,8 +215,12 @@ def test_build_jenkins_with_parameters_and_wait_until_job_done_when_http_excepti self.jenkins.create_session_jenkins('http', 'localhost:8080', 'username', 'password', False) try: - self.jenkins.build_jenkins_with_parameters_and_wait_until_job_done('folder_name/test_job', - 'data_test', retry=1) + self.jenkins.build_jenkins_with_parameters_and_wait_until_job_done( + 'folder_name/test_job', + 'data_test', + retry=1, + ignore_exception=False + ) except requests.exceptions.HTTPError as err: self.assertTrue(err.response.status_code == 500) @@ -212,7 +272,11 @@ def test_build_jenkins_with_parameters_and_wait_until_job_done_when_exception(se raised = False try: - self.jenkins.build_jenkins_with_parameters_and_wait_until_job_done('folder_name/test_job', 'data_test') + self.jenkins.build_jenkins_with_parameters_and_wait_until_job_done( + name='folder_name/test_job', + data='data_test', + ignore_exception=False + ) except requests.exceptions.ConnectionError: raised = True From 6f63600e0d9114c2edcc5ac4cb1b852d2f1a1e1b Mon Sep 17 00:00:00 2001 From: Panchorn Lertvipada Date: Thu, 28 Apr 2022 10:27:06 +0700 Subject: [PATCH 2/4] Update requirement.txt and regen docs --- docs/JenkinsLibrary.html | 2 +- requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/JenkinsLibrary.html b/docs/JenkinsLibrary.html index 9c7e9cd..e89b5eb 100644 --- a/docs/JenkinsLibrary.html +++ b/docs/JenkinsLibrary.html @@ -614,7 +614,7 @@ jQuery.extend({highlight:function(e,t,n,r){if(e.nodeType===3){var i=e.data.match(t);if(i){var s=document.createElement(n||"span");s.className=r||"highlight";var o=e.splitText(i.index);o.splitText(i[0].length);var u=o.cloneNode(true);s.appendChild(u);o.parentNode.replaceChild(s,o);return 1}}else if(e.nodeType===1&&e.childNodes&&!/(script|style)/i.test(e.tagName)&&!(e.tagName===n.toUpperCase()&&e.className===r)){for(var a=0;a diff --git a/requirements.txt b/requirements.txt index 3c464f1..7d864bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ robotframework==3.2.2 pytest==6.2.4 pytest-cov==2.12.1 codecov==2.1.12 -requests_mock==1.9.3 \ No newline at end of file +requests_mock==1.9.3 +wheel==0.37.1 \ No newline at end of file From 38d0b0a7e33523c4af7da4403a783844019293f0 Mon Sep 17 00:00:00 2001 From: Panchorn Lertvipada Date: Thu, 28 Apr 2022 10:31:06 +0700 Subject: [PATCH 3/4] Remove wheel --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7d864bd..3c464f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,4 @@ robotframework==3.2.2 pytest==6.2.4 pytest-cov==2.12.1 codecov==2.1.12 -requests_mock==1.9.3 -wheel==0.37.1 \ No newline at end of file +requests_mock==1.9.3 \ No newline at end of file From afb06575b523afe0b7e43159d32e0659ea556437 Mon Sep 17 00:00:00 2001 From: Panchorn Lertvipada Date: Thu, 28 Apr 2022 10:33:40 +0700 Subject: [PATCH 4/4] Upgrade version python in travis to 3.9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index db67f87..5490ea2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ dist: xenial language: python python: -- '3.7' +- '3.9' install: pip install -r requirements.txt script: - pytest -vv --cov=./ --cov-report=xml