Merge lp:~fginther/cupstream2distro-config/independent-triggering into lp:cupstream2distro-config

Proposed by Francis Ginther
Status: Merged
Approved by: Francis Ginther
Approved revision: 843
Merged at revision: 844
Proposed branch: lp:~fginther/cupstream2distro-config/independent-triggering
Merge into: lp:cupstream2distro-config
Diff against target: 350 lines (+128/-52)
2 files modified
c2dconfigutils/cu2dTrigger.py (+37/-27)
tests/test_cu2dTrigger.py (+91/-25)
To merge this branch: bzr merge lp:~fginther/cupstream2distro-config/independent-triggering
Reviewer Review Type Date Requested Status
Joe Talbott (community) Approve
Francis Ginther Needs Resubmitting
PS Jenkins bot continuous-integration Approve
Review via email: mp+189953@code.launchpad.net

Commit message

Allow independent triggering of ci and autolanding jobs for entire stacks.

Description of the change

Allow independent triggering of ci and autolanding for entire stacks.

This primarily contains changes to the argument handling to change the behavior of the --trigger-ci and --trigger-autolanding flags. One or both of these is now required to specify the type of jobs to trigger. This was already being done for single branches, now this also applies to stacks.

Here are examples of this in action:
http://10.97.0.26:8080/job/trigger-ci-on-stacks/1/
http://10.97.0.26:8080/job/trigger-autolanding-on-stacks/1/

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Joe Talbott (joetalbott) wrote :

L97 here trigger_types will either be ['autolanding'] or ['ci'] but in other places I see trigger_types being set to ['autolanding', 'ci']. I might be missing some context.

review: Needs Information
Revision history for this message
Francis Ginther (fginther) wrote :

> L97 here trigger_types will either be ['autolanding'] or ['ci'] but in other
> places I see trigger_types being set to ['autolanding', 'ci']. I might be
> missing some context.

Good catch. This

100 + else:

should be:

if args.trigger_ci:

I want to enable both types of jobs if the arguments are there.

Revision history for this message
Francis Ginther (fginther) :
review: Needs Fixing
843. By Francis Ginther

Should be able to trigger autolanding and ci jobs, not either/or.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Francis Ginther (fginther) :
review: Needs Resubmitting
Revision history for this message
Joe Talbott (joetalbott) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'c2dconfigutils/cu2dTrigger.py'
--- c2dconfigutils/cu2dTrigger.py 2013-05-13 18:19:16 +0000
+++ c2dconfigutils/cu2dTrigger.py 2013-10-08 21:15:00 +0000
@@ -59,21 +59,25 @@
59 'Useful when using -c or -l ' +59 'Useful when using -c or -l ' +
60 '(default: {}).'.format(60 '(default: {}).'.format(
61 self.DEFAULT_STACKS_CFG_PATH))61 self.DEFAULT_STACKS_CFG_PATH))
62 parser.add_argument('-c', '--trigger-ci',62 parser.add_argument('-b', '--branch',
63 default=None,63 default=None,
64 help='trigger ci job on the defined target branch')64 help='target source branch to search')
65 parser.add_argument('-l', '--trigger-autolanding',65 parser.add_argument('-c', '--trigger-ci', action='store_true',
66 default=None,66 default=False,
67 help='Trigger autolanding on the defined' +67 help='trigger ci jobs')
68 ' target branch')68 parser.add_argument('-l', '--trigger-autolanding', action='store_true',
69 default=False,
70 help='Trigger autolanding jobs')
69 parser.add_argument('stackcfg', nargs='?',71 parser.add_argument('stackcfg', nargs='?',
70 help='Path to a configuration file for the stack',72 help='Path to a configuration file for the stack',
71 default=None)73 default=None)
72 args = parser.parse_args()74 args = parser.parse_args()
7375
74 if not args.stackcfg and \76 if not args.stackcfg and not args.branch:
75 not args.trigger_ci and not args.trigger_autolanding:77 parser.error('Either -b/--branch or stackcfg must be defined')
76 parser.error('One of -c, -l or stackcfg must be defined')78 if not args.trigger_ci and not args.trigger_autolanding:
79 parser.error('Must specify -c/--trigger-ci or '
80 '-l/--trigger-autolanding or both')
77 return args81 return args
7882
79 def generate_trigger(self, project_name, project_config, job_type):83 def generate_trigger(self, project_name, project_config, job_type):
@@ -98,7 +102,7 @@
98 'branch': branch,102 'branch': branch,
99 'options': options}103 'options': options}
100104
101 def process_stack(self, stack):105 def process_stack(self, stack, trigger_types):
102 """ Generate a list of job triggers from the projects within a stack106 """ Generate a list of job triggers from the projects within a stack
103107
104 :param stack: dictionary with configuration of the stack108 :param stack: dictionary with configuration of the stack
@@ -113,7 +117,7 @@
113 project_config = copy.deepcopy(stack['ci_default'])117 project_config = copy.deepcopy(stack['ci_default'])
114 dict_union(project_config, stack[section_name][project_name])118 dict_union(project_config, stack[section_name][project_name])
115119
116 for job_type in ['ci', 'autolanding']:120 for job_type in trigger_types:
117 if project_config.get(job_type + '_template', None):121 if project_config.get(job_type + '_template', None):
118 trigger_list.append(self.generate_trigger(122 trigger_list.append(self.generate_trigger(
119 project_name, project_config, job_type))123 project_name, project_config, job_type))
@@ -150,7 +154,8 @@
150 else:154 else:
151 return result155 return result
152156
153 def trigger_stack(self, default_config, stackcfg, plugin_path):157 def trigger_stack(self, default_config, stackcfg, plugin_path,
158 trigger_types):
154 lock_name = self._get_lock_name(stackcfg)159 lock_name = self._get_lock_name(stackcfg)
155 stackcfg = load_stack_cfg(stackcfg, default_config)160 stackcfg = load_stack_cfg(stackcfg, default_config)
156 if not stackcfg:161 if not stackcfg:
@@ -158,7 +163,7 @@
158 return 1163 return 1
159 trigger_list = []164 trigger_list = []
160 if stackcfg['projects']:165 if stackcfg['projects']:
161 trigger_list = self.process_stack(stackcfg)166 trigger_list = self.process_stack(stackcfg, trigger_types)
162167
163 for trigger in trigger_list:168 for trigger in trigger_list:
164 self.trigger_job(plugin_path, trigger, lock_name)169 self.trigger_job(plugin_path, trigger, lock_name)
@@ -192,10 +197,12 @@
192 return None197 return None
193198
194 def trigger_project(self, plugin_path, default_config, trigger_branch,199 def trigger_project(self, plugin_path, default_config, trigger_branch,
195 stackcfg_dir, trigger_type):200 stackcfg_dir, trigger_types):
196201
197 trigger = self.get_trigger_for_target(default_config, trigger_branch,202 for job_type in trigger_types:
198 stackcfg_dir, trigger_type)203 trigger = self.get_trigger_for_target(default_config,
204 trigger_branch,
205 stackcfg_dir, job_type)
199 if not trigger:206 if not trigger:
200 return 1207 return 1
201 self.trigger_job(plugin_path, trigger, lock_name='target-branch')208 self.trigger_job(plugin_path, trigger, lock_name='target-branch')
@@ -207,16 +214,19 @@
207214
208 set_logging(args.debug)215 set_logging(args.debug)
209 default_config = load_default_cfg(default_config_path)216 default_config = load_default_cfg(default_config_path)
217 trigger_types = []
218 if args.trigger_autolanding:
219 trigger_types.append('autolanding')
220 if args.trigger_ci:
221 trigger_types.append('ci')
210 if args.stackcfg:222 if args.stackcfg:
211 return self.trigger_stack(default_config,223 return self.trigger_stack(default_config,
212 args.stackcfg,224 args.stackcfg,
213 args.plugin_path)225 args.plugin_path,
214 if args.trigger_autolanding:226 trigger_types)
215 trigger_type = 'autolanding'227 if args.branch and args.stackcfg_dir:
216 trigger_branch = args.trigger_autolanding228 return self.trigger_project(args.plugin_path, default_config,
217 else:229 args.branch, args.stackcfg_dir,
218 trigger_type = 'ci'230 trigger_types)
219 trigger_branch = args.trigger_ci231 logging.error('Invalid arguments')
220 return self.trigger_project(args.plugin_path, default_config,232 return -1
221 trigger_branch, args.stackcfg_dir,
222 trigger_type)
223233
=== modified file 'tests/test_cu2dTrigger.py'
--- tests/test_cu2dTrigger.py 2013-05-15 16:41:46 +0000
+++ tests/test_cu2dTrigger.py 2013-10-08 21:15:00 +0000
@@ -107,9 +107,10 @@
107107
108 def setUp(self):108 def setUp(self):
109 self.jt = JobTrigger()109 self.jt = JobTrigger()
110 self.trigger_types = ['ci', 'autolanding']
110111
111 def test_process_stack(self):112 def test_process_stack(self):
112 ret = self.jt.process_stack(self.stack)113 ret = self.jt.process_stack(self.stack, self.trigger_types)
113 self.assertEqual(self.expected_result, ret)114 self.assertEqual(self.expected_result, ret)
114115
115116
@@ -189,6 +190,7 @@
189 self.plugin_path = '/tmp'190 self.plugin_path = '/tmp'
190 self.stack_cfg = {'projects': {'foo': {},191 self.stack_cfg = {'projects': {'foo': {},
191 'bar': {}}}192 'bar': {}}}
193 self.trigger_types = ['ci', 'autolanding']
192 self.jt = JobTrigger()194 self.jt = JobTrigger()
193 self.jt.process_stack = MagicMock(return_value=['trigger'])195 self.jt.process_stack = MagicMock(return_value=['trigger'])
194 self.jt.trigger_job = MagicMock()196 self.jt.trigger_job = MagicMock()
@@ -198,9 +200,10 @@
198 """Verifiy jobs are triggered for a valid stack"""200 """Verifiy jobs are triggered for a valid stack"""
199 load_stack_cfg.return_value = self.stack_cfg201 load_stack_cfg.return_value = self.stack_cfg
200 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,202 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
201 self.plugin_path)203 self.plugin_path, self.trigger_types)
202 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})204 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
203 self.jt.process_stack.assert_called_with(self.stack_cfg)205 self.jt.process_stack.assert_called_with(self.stack_cfg,
206 self.trigger_types)
204 self.jt.trigger_job.assert_called_with(self.plugin_path, 'trigger',207 self.jt.trigger_job.assert_called_with(self.plugin_path, 'trigger',
205 'head-foobar.cfg')208 'head-foobar.cfg')
206 self.assertEqual(ret, 0)209 self.assertEqual(ret, 0)
@@ -210,7 +213,7 @@
210 """Verify no jobs are triggered when stack file fails to load"""213 """Verify no jobs are triggered when stack file fails to load"""
211 load_stack_cfg.return_value = False214 load_stack_cfg.return_value = False
212 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,215 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
213 self.plugin_path)216 self.plugin_path, self.trigger_types)
214 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})217 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
215 self.assertFalse(self.jt.process_stack.called)218 self.assertFalse(self.jt.process_stack.called)
216 self.assertFalse(self.jt.trigger_job.called)219 self.assertFalse(self.jt.trigger_job.called)
@@ -221,7 +224,7 @@
221 """Verify no jobs are triggered when no project section"""224 """Verify no jobs are triggered when no project section"""
222 load_stack_cfg.return_value = {}225 load_stack_cfg.return_value = {}
223 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,226 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
224 self.plugin_path)227 self.plugin_path, self.trigger_types)
225 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})228 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
226 self.assertFalse(self.jt.process_stack.called)229 self.assertFalse(self.jt.process_stack.called)
227 self.assertFalse(self.jt.trigger_job.called)230 self.assertFalse(self.jt.trigger_job.called)
@@ -234,7 +237,7 @@
234 'to_transition': {'foo': {},237 'to_transition': {'foo': {},
235 'bar': {}}}238 'bar': {}}}
236 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,239 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
237 self.plugin_path)240 self.plugin_path, self.trigger_types)
238 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})241 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
239 self.assertFalse(self.jt.process_stack.called)242 self.assertFalse(self.jt.process_stack.called)
240 self.assertFalse(self.jt.trigger_job.called)243 self.assertFalse(self.jt.trigger_job.called)
@@ -246,9 +249,10 @@
246 load_stack_cfg.return_value = self.stack_cfg249 load_stack_cfg.return_value = self.stack_cfg
247 self.jt.process_stack = MagicMock(return_value=[])250 self.jt.process_stack = MagicMock(return_value=[])
248 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,251 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
249 self.plugin_path)252 self.plugin_path, self.trigger_types)
250 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})253 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
251 self.jt.process_stack.assert_called_with(self.stack_cfg)254 self.jt.process_stack.assert_called_with(self.stack_cfg,
255 self.trigger_types)
252 self.assertFalse(self.jt.trigger_job.called)256 self.assertFalse(self.jt.trigger_job.called)
253 self.assertEqual(ret, 0)257 self.assertEqual(ret, 0)
254258
@@ -256,15 +260,18 @@
256class TestTriggerBranch(TestWithScenarios, TestCase):260class TestTriggerBranch(TestWithScenarios, TestCase):
257 scenarios = [261 scenarios = [
258 ('ci',262 ('ci',
259 {'trigger_type': 'ci',263 {'trigger_type': ['ci'],
264 'job_type': 'ci',
260 'fasttrack': True,265 'fasttrack': True,
261 'options': ['--trigger-ci']}),266 'options': ['--trigger-ci']}),
262 ('autolanding-fasttrack',267 ('autolanding-fasttrack',
263 {'trigger_type': 'autolanding',268 {'trigger_type': ['autolanding'],
269 'job_type': 'autolanding',
264 'fasttrack': True,270 'fasttrack': True,
265 'options': ['--autoland', '--fasttrack']}),271 'options': ['--autoland', '--fasttrack']}),
266 ('autolanding-nofasttrack',272 ('autolanding-nofasttrack',
267 {'trigger_type': 'autolanding',273 {'trigger_type': ['autolanding'],
274 'job_type': 'autolanding',
268 'fasttrack': False,275 'fasttrack': False,
269 'options': ['--autoland']}),276 'options': ['--autoland']}),
270 ]277 ]
@@ -284,7 +291,7 @@
284 self.trigger_type)291 self.trigger_type)
285 jt.get_trigger_for_target.assert_called_once_with(292 jt.get_trigger_for_target.assert_called_once_with(
286 self.default_config, self.target_branch,293 self.default_config, self.target_branch,
287 self.stackcfg_dir, self.trigger_type)294 self.stackcfg_dir, self.job_type)
288 jt.trigger_job.assert_called_once_with(self.plugin_path, trigger,295 jt.trigger_job.assert_called_once_with(self.plugin_path, trigger,
289 lock_name='target-branch')296 lock_name='target-branch')
290 self.assertEqual(ret, 0)297 self.assertEqual(ret, 0)
@@ -322,9 +329,9 @@
322 trigger = jt.get_trigger_for_target(self.default_config,329 trigger = jt.get_trigger_for_target(self.default_config,
323 self.target_branch,330 self.target_branch,
324 self.stackcfg_dir,331 self.stackcfg_dir,
325 self.trigger_type)332 self.job_type)
326 expected_trigger = {333 expected_trigger = {
327 'name': 'branch-{}'.format(self.trigger_type),334 'name': 'branch-{}'.format(self.job_type),
328 'branch': self.target_branch,335 'branch': self.target_branch,
329 'options': self.options336 'options': self.options
330 }337 }
@@ -367,12 +374,38 @@
367374
368 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')375 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
369 def test_stackcfg_defined(self, load_default_cfg):376 def test_stackcfg_defined(self, load_default_cfg):
377 sys_argv = ['./command', '--trigger-ci', '../stacks/head/stack.cfg']
378 with patch('sys.argv', sys_argv):
379 jt = JobTrigger()
380 jt.trigger_stack = MagicMock()
381 jt('')
382 jt.trigger_stack.assert_called_once()
383
384 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
385 def test_trigger_ci_and_autolanding_stack(self, load_default_cfg):
386 load_default_cfg.return_value = {}
387 sys_argv = ['./command', '--trigger-ci', '--trigger-autolanding',
388 '../stacks/head/stack.cfg']
389 with patch('sys.argv', sys_argv):
390 jt = JobTrigger()
391 jt.trigger_stack = MagicMock()
392 jt('')
393 jt.trigger_stack.assert_called_once_with(
394 {}, '../stacks/head/stack.cfg',
395 JobTrigger.DEFAULT_PLUGIN_PATH,
396 ['autolanding', 'ci'])
397
398 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
399 def test_missing_type(self, load_default_cfg):
370 sys_argv = ['./command', '../stacks/head/stack.cfg']400 sys_argv = ['./command', '../stacks/head/stack.cfg']
371 with patch('sys.argv', sys_argv):401 with patch('sys.argv', sys_argv):
372 jt = JobTrigger()402 jt = JobTrigger()
373 jt.trigger_stack = MagicMock()403 jt.trigger_stack = MagicMock()
374 jt('')404 try:
375 jt.trigger_stack.assert_called_once()405 jt('')
406 except SystemExit:
407 exception = True
408 self.assertTrue(exception)
376409
377 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')410 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
378 def test_trigger_autolanding(self, load_default_cfg):411 def test_trigger_autolanding(self, load_default_cfg):
@@ -381,13 +414,13 @@
381 plugin_path = '/plugin/path'414 plugin_path = '/plugin/path'
382 cfg_dir = '../stacks'415 cfg_dir = '../stacks'
383 sys_argv = ['./command', '--trigger-autolanding',416 sys_argv = ['./command', '--trigger-autolanding',
384 branch, '-p', plugin_path, '-D', cfg_dir]417 '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
385 with patch('sys.argv', sys_argv):418 with patch('sys.argv', sys_argv):
386 jt = JobTrigger()419 jt = JobTrigger()
387 jt.trigger_project = MagicMock()420 jt.trigger_project = MagicMock()
388 jt('')421 jt('')
389 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,422 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
390 cfg_dir, 'autolanding')423 cfg_dir, ['autolanding'])
391424
392 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')425 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
393 def test_trigger_ci(self, load_default_cfg):426 def test_trigger_ci(self, load_default_cfg):
@@ -396,10 +429,43 @@
396 plugin_path = '/plugin/path'429 plugin_path = '/plugin/path'
397 cfg_dir = '../stacks'430 cfg_dir = '../stacks'
398 sys_argv = ['./command', '--trigger-ci',431 sys_argv = ['./command', '--trigger-ci',
399 branch, '-p', plugin_path, '-D', cfg_dir]432 '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
400 with patch('sys.argv', sys_argv):433 with patch('sys.argv', sys_argv):
401 jt = JobTrigger()434 jt = JobTrigger()
402 jt.trigger_project = MagicMock()435 jt.trigger_project = MagicMock()
403 jt('')436 jt('')
404 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,437 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
405 cfg_dir, 'ci')438 cfg_dir, ['ci'])
439
440 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
441 def test_trigger_ci_and_autolanding_branch(self, load_default_cfg):
442 load_default_cfg.return_value = {}
443 branch = 'lp:branch'
444 plugin_path = '/plugin/path'
445 cfg_dir = '../stacks'
446 sys_argv = ['./command', '--trigger-ci', '--trigger-autolanding',
447 '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
448 with patch('sys.argv', sys_argv):
449 jt = JobTrigger()
450 jt.trigger_project = MagicMock()
451 jt('')
452 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
453 cfg_dir,
454 ['autolanding', 'ci'])
455
456 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
457 def test_trigger_ci_missing_branch(self, load_default_cfg):
458 load_default_cfg.return_value = {}
459 branch = 'lp:branch'
460 plugin_path = '/plugin/path'
461 cfg_dir = '../stacks'
462 sys_argv = ['./command', '--trigger-ci',
463 '-p', plugin_path, '-D', cfg_dir]
464 with patch('sys.argv', sys_argv):
465 jt = JobTrigger()
466 jt.trigger_project = MagicMock()
467 try:
468 jt('')
469 except SystemExit:
470 exception = True
471 self.assertTrue(exception)

Subscribers

People subscribed via source and target branches

to all changes: