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
1=== modified file 'c2dconfigutils/cu2dTrigger.py'
2--- c2dconfigutils/cu2dTrigger.py 2013-05-13 18:19:16 +0000
3+++ c2dconfigutils/cu2dTrigger.py 2013-10-08 21:15:00 +0000
4@@ -59,21 +59,25 @@
5 'Useful when using -c or -l ' +
6 '(default: {}).'.format(
7 self.DEFAULT_STACKS_CFG_PATH))
8- parser.add_argument('-c', '--trigger-ci',
9- default=None,
10- help='trigger ci job on the defined target branch')
11- parser.add_argument('-l', '--trigger-autolanding',
12- default=None,
13- help='Trigger autolanding on the defined' +
14- ' target branch')
15+ parser.add_argument('-b', '--branch',
16+ default=None,
17+ help='target source branch to search')
18+ parser.add_argument('-c', '--trigger-ci', action='store_true',
19+ default=False,
20+ help='trigger ci jobs')
21+ parser.add_argument('-l', '--trigger-autolanding', action='store_true',
22+ default=False,
23+ help='Trigger autolanding jobs')
24 parser.add_argument('stackcfg', nargs='?',
25 help='Path to a configuration file for the stack',
26 default=None)
27 args = parser.parse_args()
28
29- if not args.stackcfg and \
30- not args.trigger_ci and not args.trigger_autolanding:
31- parser.error('One of -c, -l or stackcfg must be defined')
32+ if not args.stackcfg and not args.branch:
33+ parser.error('Either -b/--branch or stackcfg must be defined')
34+ if not args.trigger_ci and not args.trigger_autolanding:
35+ parser.error('Must specify -c/--trigger-ci or '
36+ '-l/--trigger-autolanding or both')
37 return args
38
39 def generate_trigger(self, project_name, project_config, job_type):
40@@ -98,7 +102,7 @@
41 'branch': branch,
42 'options': options}
43
44- def process_stack(self, stack):
45+ def process_stack(self, stack, trigger_types):
46 """ Generate a list of job triggers from the projects within a stack
47
48 :param stack: dictionary with configuration of the stack
49@@ -113,7 +117,7 @@
50 project_config = copy.deepcopy(stack['ci_default'])
51 dict_union(project_config, stack[section_name][project_name])
52
53- for job_type in ['ci', 'autolanding']:
54+ for job_type in trigger_types:
55 if project_config.get(job_type + '_template', None):
56 trigger_list.append(self.generate_trigger(
57 project_name, project_config, job_type))
58@@ -150,7 +154,8 @@
59 else:
60 return result
61
62- def trigger_stack(self, default_config, stackcfg, plugin_path):
63+ def trigger_stack(self, default_config, stackcfg, plugin_path,
64+ trigger_types):
65 lock_name = self._get_lock_name(stackcfg)
66 stackcfg = load_stack_cfg(stackcfg, default_config)
67 if not stackcfg:
68@@ -158,7 +163,7 @@
69 return 1
70 trigger_list = []
71 if stackcfg['projects']:
72- trigger_list = self.process_stack(stackcfg)
73+ trigger_list = self.process_stack(stackcfg, trigger_types)
74
75 for trigger in trigger_list:
76 self.trigger_job(plugin_path, trigger, lock_name)
77@@ -192,10 +197,12 @@
78 return None
79
80 def trigger_project(self, plugin_path, default_config, trigger_branch,
81- stackcfg_dir, trigger_type):
82+ stackcfg_dir, trigger_types):
83
84- trigger = self.get_trigger_for_target(default_config, trigger_branch,
85- stackcfg_dir, trigger_type)
86+ for job_type in trigger_types:
87+ trigger = self.get_trigger_for_target(default_config,
88+ trigger_branch,
89+ stackcfg_dir, job_type)
90 if not trigger:
91 return 1
92 self.trigger_job(plugin_path, trigger, lock_name='target-branch')
93@@ -207,16 +214,19 @@
94
95 set_logging(args.debug)
96 default_config = load_default_cfg(default_config_path)
97+ trigger_types = []
98+ if args.trigger_autolanding:
99+ trigger_types.append('autolanding')
100+ if args.trigger_ci:
101+ trigger_types.append('ci')
102 if args.stackcfg:
103 return self.trigger_stack(default_config,
104 args.stackcfg,
105- args.plugin_path)
106- if args.trigger_autolanding:
107- trigger_type = 'autolanding'
108- trigger_branch = args.trigger_autolanding
109- else:
110- trigger_type = 'ci'
111- trigger_branch = args.trigger_ci
112- return self.trigger_project(args.plugin_path, default_config,
113- trigger_branch, args.stackcfg_dir,
114- trigger_type)
115+ args.plugin_path,
116+ trigger_types)
117+ if args.branch and args.stackcfg_dir:
118+ return self.trigger_project(args.plugin_path, default_config,
119+ args.branch, args.stackcfg_dir,
120+ trigger_types)
121+ logging.error('Invalid arguments')
122+ return -1
123
124=== modified file 'tests/test_cu2dTrigger.py'
125--- tests/test_cu2dTrigger.py 2013-05-15 16:41:46 +0000
126+++ tests/test_cu2dTrigger.py 2013-10-08 21:15:00 +0000
127@@ -107,9 +107,10 @@
128
129 def setUp(self):
130 self.jt = JobTrigger()
131+ self.trigger_types = ['ci', 'autolanding']
132
133 def test_process_stack(self):
134- ret = self.jt.process_stack(self.stack)
135+ ret = self.jt.process_stack(self.stack, self.trigger_types)
136 self.assertEqual(self.expected_result, ret)
137
138
139@@ -189,6 +190,7 @@
140 self.plugin_path = '/tmp'
141 self.stack_cfg = {'projects': {'foo': {},
142 'bar': {}}}
143+ self.trigger_types = ['ci', 'autolanding']
144 self.jt = JobTrigger()
145 self.jt.process_stack = MagicMock(return_value=['trigger'])
146 self.jt.trigger_job = MagicMock()
147@@ -198,9 +200,10 @@
148 """Verifiy jobs are triggered for a valid stack"""
149 load_stack_cfg.return_value = self.stack_cfg
150 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
151- self.plugin_path)
152+ self.plugin_path, self.trigger_types)
153 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
154- self.jt.process_stack.assert_called_with(self.stack_cfg)
155+ self.jt.process_stack.assert_called_with(self.stack_cfg,
156+ self.trigger_types)
157 self.jt.trigger_job.assert_called_with(self.plugin_path, 'trigger',
158 'head-foobar.cfg')
159 self.assertEqual(ret, 0)
160@@ -210,7 +213,7 @@
161 """Verify no jobs are triggered when stack file fails to load"""
162 load_stack_cfg.return_value = False
163 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
164- self.plugin_path)
165+ self.plugin_path, self.trigger_types)
166 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
167 self.assertFalse(self.jt.process_stack.called)
168 self.assertFalse(self.jt.trigger_job.called)
169@@ -221,7 +224,7 @@
170 """Verify no jobs are triggered when no project section"""
171 load_stack_cfg.return_value = {}
172 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
173- self.plugin_path)
174+ self.plugin_path, self.trigger_types)
175 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
176 self.assertFalse(self.jt.process_stack.called)
177 self.assertFalse(self.jt.trigger_job.called)
178@@ -234,7 +237,7 @@
179 'to_transition': {'foo': {},
180 'bar': {}}}
181 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
182- self.plugin_path)
183+ self.plugin_path, self.trigger_types)
184 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
185 self.assertFalse(self.jt.process_stack.called)
186 self.assertFalse(self.jt.trigger_job.called)
187@@ -246,9 +249,10 @@
188 load_stack_cfg.return_value = self.stack_cfg
189 self.jt.process_stack = MagicMock(return_value=[])
190 ret = self.jt.trigger_stack(self.default_config, self.stack_cfg_name,
191- self.plugin_path)
192+ self.plugin_path, self.trigger_types)
193 load_stack_cfg.assert_called_with('stacks/head/foobar.cfg', {})
194- self.jt.process_stack.assert_called_with(self.stack_cfg)
195+ self.jt.process_stack.assert_called_with(self.stack_cfg,
196+ self.trigger_types)
197 self.assertFalse(self.jt.trigger_job.called)
198 self.assertEqual(ret, 0)
199
200@@ -256,15 +260,18 @@
201 class TestTriggerBranch(TestWithScenarios, TestCase):
202 scenarios = [
203 ('ci',
204- {'trigger_type': 'ci',
205+ {'trigger_type': ['ci'],
206+ 'job_type': 'ci',
207 'fasttrack': True,
208 'options': ['--trigger-ci']}),
209 ('autolanding-fasttrack',
210- {'trigger_type': 'autolanding',
211+ {'trigger_type': ['autolanding'],
212+ 'job_type': 'autolanding',
213 'fasttrack': True,
214 'options': ['--autoland', '--fasttrack']}),
215 ('autolanding-nofasttrack',
216- {'trigger_type': 'autolanding',
217+ {'trigger_type': ['autolanding'],
218+ 'job_type': 'autolanding',
219 'fasttrack': False,
220 'options': ['--autoland']}),
221 ]
222@@ -284,7 +291,7 @@
223 self.trigger_type)
224 jt.get_trigger_for_target.assert_called_once_with(
225 self.default_config, self.target_branch,
226- self.stackcfg_dir, self.trigger_type)
227+ self.stackcfg_dir, self.job_type)
228 jt.trigger_job.assert_called_once_with(self.plugin_path, trigger,
229 lock_name='target-branch')
230 self.assertEqual(ret, 0)
231@@ -322,9 +329,9 @@
232 trigger = jt.get_trigger_for_target(self.default_config,
233 self.target_branch,
234 self.stackcfg_dir,
235- self.trigger_type)
236+ self.job_type)
237 expected_trigger = {
238- 'name': 'branch-{}'.format(self.trigger_type),
239+ 'name': 'branch-{}'.format(self.job_type),
240 'branch': self.target_branch,
241 'options': self.options
242 }
243@@ -367,12 +374,38 @@
244
245 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
246 def test_stackcfg_defined(self, load_default_cfg):
247+ sys_argv = ['./command', '--trigger-ci', '../stacks/head/stack.cfg']
248+ with patch('sys.argv', sys_argv):
249+ jt = JobTrigger()
250+ jt.trigger_stack = MagicMock()
251+ jt('')
252+ jt.trigger_stack.assert_called_once()
253+
254+ @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
255+ def test_trigger_ci_and_autolanding_stack(self, load_default_cfg):
256+ load_default_cfg.return_value = {}
257+ sys_argv = ['./command', '--trigger-ci', '--trigger-autolanding',
258+ '../stacks/head/stack.cfg']
259+ with patch('sys.argv', sys_argv):
260+ jt = JobTrigger()
261+ jt.trigger_stack = MagicMock()
262+ jt('')
263+ jt.trigger_stack.assert_called_once_with(
264+ {}, '../stacks/head/stack.cfg',
265+ JobTrigger.DEFAULT_PLUGIN_PATH,
266+ ['autolanding', 'ci'])
267+
268+ @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
269+ def test_missing_type(self, load_default_cfg):
270 sys_argv = ['./command', '../stacks/head/stack.cfg']
271 with patch('sys.argv', sys_argv):
272 jt = JobTrigger()
273 jt.trigger_stack = MagicMock()
274- jt('')
275- jt.trigger_stack.assert_called_once()
276+ try:
277+ jt('')
278+ except SystemExit:
279+ exception = True
280+ self.assertTrue(exception)
281
282 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
283 def test_trigger_autolanding(self, load_default_cfg):
284@@ -381,13 +414,13 @@
285 plugin_path = '/plugin/path'
286 cfg_dir = '../stacks'
287 sys_argv = ['./command', '--trigger-autolanding',
288- branch, '-p', plugin_path, '-D', cfg_dir]
289+ '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
290 with patch('sys.argv', sys_argv):
291 jt = JobTrigger()
292 jt.trigger_project = MagicMock()
293 jt('')
294 jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
295- cfg_dir, 'autolanding')
296+ cfg_dir, ['autolanding'])
297
298 @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
299 def test_trigger_ci(self, load_default_cfg):
300@@ -396,10 +429,43 @@
301 plugin_path = '/plugin/path'
302 cfg_dir = '../stacks'
303 sys_argv = ['./command', '--trigger-ci',
304- branch, '-p', plugin_path, '-D', cfg_dir]
305- with patch('sys.argv', sys_argv):
306- jt = JobTrigger()
307- jt.trigger_project = MagicMock()
308- jt('')
309- jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
310- cfg_dir, 'ci')
311+ '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
312+ with patch('sys.argv', sys_argv):
313+ jt = JobTrigger()
314+ jt.trigger_project = MagicMock()
315+ jt('')
316+ jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
317+ cfg_dir, ['ci'])
318+
319+ @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
320+ def test_trigger_ci_and_autolanding_branch(self, load_default_cfg):
321+ load_default_cfg.return_value = {}
322+ branch = 'lp:branch'
323+ plugin_path = '/plugin/path'
324+ cfg_dir = '../stacks'
325+ sys_argv = ['./command', '--trigger-ci', '--trigger-autolanding',
326+ '--branch', branch, '-p', plugin_path, '-D', cfg_dir]
327+ with patch('sys.argv', sys_argv):
328+ jt = JobTrigger()
329+ jt.trigger_project = MagicMock()
330+ jt('')
331+ jt.trigger_project.assert_called_once_with(plugin_path, {}, branch,
332+ cfg_dir,
333+ ['autolanding', 'ci'])
334+
335+ @patch('c2dconfigutils.cu2dTrigger.load_default_cfg')
336+ def test_trigger_ci_missing_branch(self, load_default_cfg):
337+ load_default_cfg.return_value = {}
338+ branch = 'lp:branch'
339+ plugin_path = '/plugin/path'
340+ cfg_dir = '../stacks'
341+ sys_argv = ['./command', '--trigger-ci',
342+ '-p', plugin_path, '-D', cfg_dir]
343+ with patch('sys.argv', sys_argv):
344+ jt = JobTrigger()
345+ jt.trigger_project = MagicMock()
346+ try:
347+ jt('')
348+ except SystemExit:
349+ exception = True
350+ self.assertTrue(exception)

Subscribers

People subscribed via source and target branches

to all changes: