python-jenkins/tests/test_promotion.py
Guido Günther 0c503b724c Add support for handling promotions
Promotions can be attached to jobs via the REST API described at:

https://issues.jenkins-ci.org/browse/JENKINS-8963

Co-Authored-By: Guido Günther <agx@sigxcpu.org>
Co-Authored-By: Joao Vale <jpvale@gmail.com>

Change-Id: I756a35f53f96ba6e46e71f36ea99f62d32b604d2
2016-01-13 18:14:39 +01:00

283 lines
11 KiB
Python

import json
from mock import patch
import jenkins
from tests.base import JenkinsTestBase
from six.moves.urllib.error import HTTPError
class JenkinsPromotionsTestBase(JenkinsTestBase):
config_xml = """<hudson.plugins.promoted__builds.PromotionProcess>
</hudson.plugins.promoted__builds.PromotionProcess>"""
class JenkinsGetPromotionNameTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
promotion_name_to_return = {u'name': 'Test Promotion'}
jenkins_mock.return_value = json.dumps(promotion_name_to_return)
promotion_name = self.j.get_promotion_name(u'Test Promotion',
u'Test Job')
self.assertEqual(promotion_name, 'Test Promotion')
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
self.make_url('job/Test%20Job/promotion/process/'
'Test%20Promotion/api/json?tree=name'))
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_return_none(self, jenkins_mock):
jenkins_mock.side_effect = jenkins.NotFoundException()
promotion_name = self.j.get_promotion_name(u'TestPromotion',
u'Test Job')
self.assertEqual(promotion_name, None)
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
self.make_url('job/Test%20Job/promotion/process/'
'TestPromotion/api/json?tree=name'))
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_unexpected_promotion_name(self, jenkins_mock):
promotion_name_to_return = {u'name': 'not the right name'}
jenkins_mock.return_value = json.dumps(promotion_name_to_return)
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.get_promotion_name(u'TestPromotion', u'TestJob')
self.assertEqual(
jenkins_mock.call_args_list[0][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/process/TestPromotion'
'/api/json?tree=name'))
self.assertEqual(
str(context_manager.exception),
'Jenkins returned an unexpected promotion name {0} '
'(expected: {1})'.format(promotion_name_to_return['name'],
'TestPromotion'))
self._check_requests(jenkins_mock.call_args_list)
class JenkinsAssertPromotionTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_promotion_missing(self, jenkins_mock):
jenkins_mock.side_effect = jenkins.NotFoundException()
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.assert_promotion_exists('NonExistent', 'TestJob')
self.assertEqual(
str(context_manager.exception),
'promotion[NonExistent] does not exist for job[TestJob]')
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_promotion_exists(self, jenkins_mock):
jenkins_mock.side_effect = [
json.dumps({'name': 'ExistingPromotion'}),
]
self.j.assert_promotion_exists('ExistingPromotion', 'TestJob')
self._check_requests(jenkins_mock.call_args_list)
class JenkinsPromotionExistsTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_promotion_missing(self, jenkins_mock):
jenkins_mock.side_effect = jenkins.NotFoundException()
self.assertEqual(self.j.promotion_exists('NonExistent', 'TestJob'),
False)
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_promotion_exists(self, jenkins_mock):
jenkins_mock.side_effect = [
json.dumps({'name': 'ExistingPromotion'}),
]
self.assertEqual(self.j.promotion_exists('ExistingPromotion',
'TestJob'),
True)
self._check_requests(jenkins_mock.call_args_list)
class JenkinsGetPromotionsTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
promotions = {
u'url': (u'http://your_url_here/jobs/TestJob/promotions'
u'/my_promotion/'),
u'name': u'my_promotion',
}
promotion_info_to_return = {u'processes': promotions}
jenkins_mock.return_value = json.dumps(promotion_info_to_return)
promotion_info = self.j.get_promotions('TestJob')
self.assertEqual(promotion_info, promotions)
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
self.make_url('job/TestJob/promotion/api/json?depth=0'))
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_nonexistent(self, jenkins_mock):
jenkins_mock.side_effect = [
None,
HTTPError,
]
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.get_promotions('TestJob')
self.assertEqual(
str(context_manager.exception),
'job[TestJob] does not exist')
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_invalid_json(self, jenkins_mock):
jenkins_mock.return_value = '{invalid_json}'
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.get_promotions('TestJob')
self.assertEqual(
str(context_manager.exception),
"Could not parse JSON info for promotions of job[TestJob]")
class JenkinsDeletePromotionTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
jenkins_mock.side_effect = [
None,
jenkins.NotFoundException(),
]
self.j.delete_promotion(u'Test Promotion', 'TestJob')
self.assertEqual(
jenkins_mock.call_args_list[0][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/process/'
'Test%20Promotion/doDelete'))
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_failed(self, jenkins_mock):
jenkins_mock.side_effect = [
json.dumps({'name': 'TestPromotion'}),
json.dumps({'name': 'TestPromotion'}),
json.dumps({'name': 'TestPromotion'}),
]
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.delete_promotion(u'TestPromotion', 'TestJob')
self.assertEqual(
jenkins_mock.call_args_list[0][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/process/'
'TestPromotion/doDelete'))
self.assertEqual(
str(context_manager.exception),
'delete[TestPromotion] from job[TestJob] failed')
self._check_requests(jenkins_mock.call_args_list)
class JenkinsCreatePromotionTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
jenkins_mock.side_effect = [
jenkins.NotFoundException(),
None,
json.dumps({'name': 'Test Promotion'}),
]
self.j.create_promotion(u'Test Promotion', 'Test Job', self.config_xml)
self.assertEqual(
jenkins_mock.call_args_list[1][0][0].get_full_url(),
self.make_url('job/Test%20Job/promotion/'
'createProcess?name=Test%20Promotion'))
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_already_exists(self, jenkins_mock):
jenkins_mock.side_effect = [
json.dumps({'name': 'TestPromotion'}),
None,
]
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.create_promotion(u'TestPromotion', 'TestJob',
self.config_xml)
self.assertEqual(
jenkins_mock.call_args_list[0][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/process/'
'TestPromotion/api/json?tree=name'))
self.assertEqual(
str(context_manager.exception),
'promotion[TestPromotion] already exists at job[TestJob]')
self._check_requests(jenkins_mock.call_args_list)
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_failed(self, jenkins_mock):
jenkins_mock.side_effect = [
jenkins.NotFoundException(),
None,
jenkins.NotFoundException(),
]
with self.assertRaises(jenkins.JenkinsException) as context_manager:
self.j.create_promotion(u'TestPromotion', 'TestJob',
self.config_xml)
self.assertEqual(
jenkins_mock.call_args_list[0][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/process/'
'TestPromotion/api/json?tree=name'))
self.assertEqual(
jenkins_mock.call_args_list[1][0][0].get_full_url(),
self.make_url('job/TestJob/promotion/'
'createProcess?name=TestPromotion'))
self.assertEqual(
str(context_manager.exception),
'create[TestPromotion] at job[TestJob] failed')
self._check_requests(jenkins_mock.call_args_list)
class JenkinsReconfigPromotionTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_simple(self, jenkins_mock):
jenkins_mock.side_effect = [
json.dumps({'name': 'Test Promotion'}),
None,
]
self.j.reconfig_promotion(u'Test Promotion', u'Test Job',
self.config_xml)
self.assertEqual(jenkins_mock.call_args[0][0].get_full_url(),
self.make_url('job/Test%20Job/promotion/process/'
'Test%20Promotion/config.xml'))
self._check_requests(jenkins_mock.call_args_list)
class JenkinsGetPromotionConfigTest(JenkinsPromotionsTestBase):
@patch.object(jenkins.Jenkins, 'jenkins_open')
def test_encodes_promotion_name(self, jenkins_mock):
self.j.get_promotion_config(u'Test Promotion', u'Test Job')
self.assertEqual(
jenkins_mock.call_args[0][0].get_full_url(),
self.make_url('job/Test%20Job/promotion/process/'
'Test%20Promotion/config.xml'))
self._check_requests(jenkins_mock.call_args_list)