Simplify 'update and delete old jobs' test
Previously this test was bound too tightly to implementation details of jenkins_jobs.builder.Builder and jenkins_jobs.parser.YamlParser; specifically, it was enforcing the relationship between these two objects by accessing the Builder's instance of the YamlParser. In order to proceed with the JJB 2.0 API refactoring, one of the goals of which is to disentangle YamlParser from Builder, this had to be rewritten. The rewrite aims to instead test at the boundaries of the JJB application --specifically by mocking out various methods in the jenkins.Jenkins class upon which JJB is built then making a command line call to jenkins-jobs using the jenkins_jobs.cli.entry.JenkinsJobs tool. The one remaining piece of questionable implementation detail binding in this test is the mocking of jenkins_jobs.builder.Jenkins.is_managed which I think is unavoidable without mocking return values on jenkins.Jenkins.get_job_config, which would be tedius and probably more effort than it's worth since deconstructing the relationship between jenkins_jobs.builder.Builder and jenkins_jobs.builder.Jenkins is not necessary for JJB 2.0 (actually, these two classes should probably just be combined into one) Change-Id: Ia0e07097e6596be2ac13140668480cefcec8334b
This commit is contained in:
parent
c569dc02d3
commit
ddb2b9c01c
tests/cmd/subcommands
@ -1,3 +1,23 @@
|
||||
# Joint copyright:
|
||||
# - Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# The goal of these tests is to check that given a particular set of flags to
|
||||
# Jenkins Job Builder's command line tools it will result in a particular set
|
||||
# of actions by the JJB library, usually through interaction with the
|
||||
# python-jenkins library.
|
||||
|
||||
import os
|
||||
|
||||
from tests.base import mock
|
||||
|
@ -1,3 +1,23 @@
|
||||
# Joint copyright:
|
||||
# - Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# The goal of these tests is to check that given a particular set of flags to
|
||||
# Jenkins Job Builder's command line tools it will result in a particular set
|
||||
# of actions by the JJB library, usually through interaction with the
|
||||
# python-jenkins library.
|
||||
|
||||
import difflib
|
||||
import filecmp
|
||||
import io
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
# Joint copyright:
|
||||
# - Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
@ -14,11 +13,14 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# The goal of these tests is to check that given a particular set of flags to
|
||||
# Jenkins Job Builder's command line tools it will result in a particular set
|
||||
# of actions by the JJB library, usually through interaction with the
|
||||
# python-jenkins library.
|
||||
|
||||
import os
|
||||
import six
|
||||
|
||||
from jenkins_jobs import builder
|
||||
from jenkins_jobs.config import JJBConfig
|
||||
from tests.base import mock
|
||||
from tests.cmd.test_cmd import CmdTestsBase
|
||||
|
||||
@ -60,71 +62,47 @@ class UpdateTests(CmdTestsBase):
|
||||
self.assertTrue(isinstance(update_job_mock.call_args[0][1],
|
||||
six.text_type))
|
||||
|
||||
@mock.patch('jenkins_jobs.builder.Jenkins.is_job', return_value=True)
|
||||
@mock.patch('jenkins_jobs.builder.Jenkins.get_jobs')
|
||||
@mock.patch('jenkins_jobs.builder.Builder.delete_job')
|
||||
@mock.patch('jenkins_jobs.cli.entry.Builder')
|
||||
def test_update_jobs_and_delete_old(self, builder_mock, delete_job_mock,
|
||||
get_jobs_mock, is_job_mock):
|
||||
@mock.patch('jenkins_jobs.builder.jenkins.Jenkins.job_exists')
|
||||
@mock.patch('jenkins_jobs.builder.jenkins.Jenkins.get_jobs')
|
||||
@mock.patch('jenkins_jobs.builder.jenkins.Jenkins.reconfig_job')
|
||||
@mock.patch('jenkins_jobs.builder.jenkins.Jenkins.delete_job')
|
||||
def test_update_jobs_and_delete_old(self,
|
||||
jenkins_delete_job,
|
||||
jenkins_reconfig_job,
|
||||
jenkins_get_jobs,
|
||||
jenkins_job_exists, ):
|
||||
"""
|
||||
Test update behaviour with --delete-old option
|
||||
|
||||
Test update of jobs with the --delete-old option enabled, where only
|
||||
some jobs result in has_changed() to limit the number of times
|
||||
update_job is called, and have the get_jobs() method return additional
|
||||
jobs not in the input yaml to test that the code in cmd will call
|
||||
delete_job() after update_job() when '--delete-old' is set but only
|
||||
for the extra managed jobs.
|
||||
* mock out a call to jenkins.Jenkins.get_jobs() to return a known list
|
||||
of job names.
|
||||
* mock out a call to jenkins.Jenkins.reconfig_job() and
|
||||
jenkins.Jenkins.delete_job() to detect calls being made to determine
|
||||
that JJB does correctly delete the jobs it should delete when passed
|
||||
a specific set of inputs.
|
||||
* mock out a call to jenkins.Jenkins.job_exists() to always return
|
||||
True.
|
||||
"""
|
||||
# set up some test data
|
||||
jobs = ['old_job001', 'old_job002', 'unmanaged']
|
||||
extra_jobs = [{'name': name} for name in jobs]
|
||||
|
||||
jjb_config = JJBConfig()
|
||||
jjb_config.jenkins['url'] = 'http://example.com'
|
||||
jjb_config.jenkins['user'] = 'doesnot'
|
||||
jjb_config.jenkins['password'] = 'matter'
|
||||
jjb_config.builder['plugins_info'] = []
|
||||
jjb_config.validate()
|
||||
builder_obj = builder.Builder(jjb_config)
|
||||
|
||||
# get the instance created by mock and redirect some of the method
|
||||
# mocks to call real methods on a the above test object.
|
||||
b_inst = builder_mock.return_value
|
||||
b_inst.plugins_list = builder_obj.plugins_list
|
||||
b_inst.update_jobs.side_effect = builder_obj.update_jobs
|
||||
b_inst.delete_old_managed.side_effect = builder_obj.delete_old_managed
|
||||
|
||||
def _get_jobs():
|
||||
return builder_obj.parser.jobs + extra_jobs
|
||||
get_jobs_mock.side_effect = _get_jobs
|
||||
|
||||
# override cache to ensure Jenkins.update_job called a limited number
|
||||
# of times
|
||||
self.cache_mock.return_value.has_changed.side_effect = (
|
||||
[True] * 2 + [False] * 2)
|
||||
|
||||
path = os.path.join(self.fixtures_path, 'cmd-002.yaml')
|
||||
args = ['--conf', self.default_config_file, 'update', '--delete-old',
|
||||
path]
|
||||
|
||||
with mock.patch('jenkins_jobs.builder.Jenkins.update_job') as update:
|
||||
with mock.patch('jenkins_jobs.builder.Jenkins.is_managed',
|
||||
side_effect=(lambda name: name != 'unmanaged')):
|
||||
self.execute_jenkins_jobs_with_args(args)
|
||||
self.assertEquals(2, update.call_count,
|
||||
"Expected Jenkins.update_job to be called '%d' "
|
||||
"times, got '%d' calls instead.\n"
|
||||
"Called with: %s" % (2, update.call_count,
|
||||
update.mock_calls))
|
||||
jenkins_get_jobs.return_value = extra_jobs
|
||||
|
||||
calls = [mock.call(name) for name in jobs if name != 'unmanaged']
|
||||
self.assertEqual(2, delete_job_mock.call_count,
|
||||
"Expected Jenkins.delete_job to be called '%d' "
|
||||
"times got '%d' calls instead.\n"
|
||||
"Called with: %s" % (2, delete_job_mock.call_count,
|
||||
delete_job_mock.mock_calls))
|
||||
delete_job_mock.assert_has_calls(calls, any_order=True)
|
||||
with mock.patch('jenkins_jobs.builder.Jenkins.is_managed',
|
||||
side_effect=(lambda name: name != 'unmanaged')):
|
||||
self.execute_jenkins_jobs_with_args(args)
|
||||
|
||||
jenkins_reconfig_job.assert_has_calls(
|
||||
[mock.call(job_name, mock.ANY)
|
||||
for job_name in ['bar001', 'bar002', 'baz001', 'bam001']],
|
||||
any_order=True
|
||||
)
|
||||
jenkins_delete_job.assert_has_calls(
|
||||
[mock.call(name) for name in jobs if name != 'unmanaged'])
|
||||
|
||||
@mock.patch('jenkins_jobs.builder.jenkins.Jenkins')
|
||||
def test_update_timeout_not_set(self, jenkins_mock):
|
||||
|
Loading…
x
Reference in New Issue
Block a user