1
from unittest import TestCase
2
from mock import Mock, patch
7
JUJUBOT_USER = {'login': 'jujubot', 'id': 7779494}
8
OTHER_USER = {'login': 'user', 'id': 1}
19
def make_fake_lp(series=False, bugs=False):
20
"""Return a fake Lp lib object based on Mocks"""
23
self_link='https://lp/j/98765', title='one', status='Triaged')
25
self_link='https://lp/j/54321', title='two', status='Triaged')
26
bugs = [task_1, task_2]
29
lp = Mock(_target=None, projects={})
33
series.searchTasks.return_value = bugs
37
project.searchTasks.return_value = bugs
39
project.getSeries.return_value = series
40
lp.projects['juju-core'] = project
44
class CheckBlockers(TestCase):
46
def test_parse_args_check(self):
47
args = check_blockers.parse_args(['check', 'MASTER', '17'])
48
self.assertEqual('check', args.command)
49
self.assertEqual('master', args.branch)
50
self.assertEqual('17', args.pull_request)
52
def test_parse_args_check_pr_optional(self):
53
args = check_blockers.parse_args(['check', 'master'])
54
self.assertEqual('check', args.command)
55
self.assertEqual('master', args.branch)
56
self.assertIsNone(args.pull_request)
58
def test_parse_args_block_ci_testing(self):
59
args = check_blockers.parse_args(['block-ci-testing', 'FEATURE'])
60
self.assertEqual('block-ci-testing', args.command)
61
self.assertEqual('feature', args.branch)
62
self.assertIsNone(args.pull_request)
64
def test_parse_args_check_branch_optional(self):
65
args = check_blockers.parse_args(['check'])
66
self.assertEqual('check', args.command)
67
self.assertEqual('master', args.branch)
68
self.assertIsNone(args.pull_request)
70
def test_parse_args_update(self):
71
args = check_blockers.parse_args(
72
['-c', './foo.cred', 'update', 'MASTER', '1234'])
73
self.assertEqual('update', args.command)
74
self.assertEqual('master', args.branch)
75
self.assertEqual('1234', args.build)
76
self.assertEqual('./foo.cred', args.credentials_file)
78
def test_main_check(self):
80
args = check_blockers.parse_args(['check', 'master', '17'])
81
with patch('check_blockers.get_lp', autospec=True,
82
return_value='lp') as gl:
83
with patch('check_blockers.get_lp_bugs', autospec=True,
84
return_value=bugs) as glb:
85
with patch('check_blockers.get_reason', autospec=True,
86
return_value=(0, 'foo')) as gr:
87
code = check_blockers.main(['check', 'master', '17'])
88
gl.assert_called_with('check_blockers', credentials_file=None)
89
glb.assert_called_with('lp', 'master', ['blocker'])
90
gr.assert_called_with(bugs, args)
91
self.assertEqual(0, code)
93
def test_main_block_ci_testing(self):
95
args = check_blockers.parse_args(['block-ci-testing', 'feature'])
96
with patch('check_blockers.get_lp', autospec=True,
97
return_value='lp') as gl:
98
with patch('check_blockers.get_lp_bugs', autospec=True,
99
return_value=bugs) as glb:
100
with patch('check_blockers.get_reason', autospec=True,
101
return_value=(0, 'foo')) as gr:
102
code = check_blockers.main(['block-ci-testing', 'feature'])
103
gl.assert_called_with('check_blockers', credentials_file=None)
104
glb.assert_called_with('lp', 'feature', ['block-ci-testing'])
105
gr.assert_called_with(bugs, args)
106
self.assertEqual(0, code)
108
def test_main_update(self):
110
argv = ['-c', './foo.cred', 'update', '--dry-run', 'master', '1234']
111
with patch('check_blockers.get_lp', autospec=True,
112
return_value='lp') as gl:
113
with patch('check_blockers.get_lp_bugs', autospec=True,
114
return_value=bugs) as glb:
115
with patch('check_blockers.update_bugs', autospec=True,
116
return_value=[0, 'Updating']) as ub:
117
code = check_blockers.main(argv)
118
gl.assert_called_with('check_blockers', credentials_file='./foo.cred')
119
glb.assert_called_with('lp', 'master', ['blocker', 'ci'])
120
ub.assert_called_with(bugs, 'master', '1234', dry_run=True)
121
self.assertEqual(0, code)
123
def test_get_lp_bugs_with_master_branch(self):
124
lp = make_fake_lp(series=False, bugs=True)
125
bugs = check_blockers.get_lp_bugs(lp, 'master', ['blocker'])
126
self.assertEqual(['54321', '98765'], sorted(bugs.keys()))
127
project = lp.projects['juju-core']
128
self.assertEqual(0, project.getSeries.call_count)
129
project.searchTasks.assert_called_with(
130
status=check_blockers.BUG_STATUSES,
131
importance=check_blockers.BUG_IMPORTANCES,
132
tags=check_blockers.BUG_TAGS, tags_combinator='All')
134
def test_get_lp_bugs_with_supported_branch(self):
135
lp = make_fake_lp(series=True, bugs=True)
136
bugs = check_blockers.get_lp_bugs(lp, '1.20', ['blocker'])
137
self.assertEqual(['54321', '98765'], sorted(bugs.keys()))
138
project = lp.projects['juju-core']
139
project.getSeries.assert_called_with(name='1.20')
141
series.searchTasks.assert_called_with(
142
status=check_blockers.BUG_STATUSES,
143
importance=check_blockers.BUG_IMPORTANCES,
144
tags=check_blockers.BUG_TAGS, tags_combinator='All')
146
def test_get_lp_bugs_with_unsupported_branch(self):
147
lp = make_fake_lp(series=False, bugs=False)
148
bugs = check_blockers.get_lp_bugs(lp, 'foo', ['blocker'])
149
self.assertEqual({}, bugs)
150
project = lp.projects['juju-core']
151
project.getSeries.assert_called_with(name='foo')
152
self.assertEqual(0, project.searchTasks.call_count)
154
def test_get_lp_bugs_without_blocking_bugs(self):
155
lp = make_fake_lp(series=False, bugs=False)
156
bugs = check_blockers.get_lp_bugs(lp, 'master', ['blocker'])
157
self.assertEqual({}, bugs)
158
project = lp.projects['juju-core']
159
project.searchTasks.assert_called_with(
160
status=check_blockers.BUG_STATUSES,
161
importance=check_blockers.BUG_IMPORTANCES,
162
tags=check_blockers.BUG_TAGS, tags_combinator='All')
164
def test_get_lp_bugs_error(self):
165
lp = make_fake_lp(series=False, bugs=True)
166
with self.assertRaises(ValueError):
167
check_blockers.get_lp_bugs(lp, 'master', [])
169
def test_get_reason_without_blocking_bugs(self):
170
args = check_blockers.parse_args(['check', 'master', '17'])
171
with patch('check_blockers.get_json') as gj:
172
code, reason = check_blockers.get_reason({}, args)
173
self.assertEqual(0, code)
174
self.assertEqual('No blocking bugs', reason)
175
self.assertEqual(0, gj.call_count)
177
def test_get_reason_without_comments(self):
178
args = check_blockers.parse_args(['check', 'master', '17'])
179
with patch('check_blockers.get_json') as gj:
181
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
182
code, reason = check_blockers.get_reason(bugs, args)
183
self.assertEqual(1, code)
184
self.assertEqual("Does not match ['fixes-98765']", reason)
185
gj.assert_called_with((check_blockers.GH_COMMENTS.format('17')))
187
def test_get_reason_with_blockers_no_match(self):
188
args = check_blockers.parse_args(['check', 'master', '17'])
189
with patch('check_blockers.get_json') as gj:
190
gj.return_value = [{'body': '$$merge$$', 'user': OTHER_USER}]
191
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
192
code, reason = check_blockers.get_reason(bugs, args)
193
self.assertEqual(1, code)
194
self.assertEqual("Does not match ['fixes-98765']", reason)
196
def test_get_reason_with_blockers_with_match(self):
197
args = check_blockers.parse_args(['check', 'master', '17'])
198
with patch('check_blockers.get_json') as gj:
200
{'body': '$$merge$$', 'user': OTHER_USER},
201
{'body': 'la la __fixes-98765__ ha ha', 'user': OTHER_USER}]
202
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
203
code, reason = check_blockers.get_reason(bugs, args)
204
self.assertEqual(0, code)
205
self.assertEqual("Matches fixes-98765", reason)
207
def test_get_reason_with_blockers_with_jujubot_comment(self):
208
args = check_blockers.parse_args(['check', 'master', '17'])
209
with patch('check_blockers.get_json') as gj:
211
{'body': '$$merge$$', 'user': OTHER_USER},
212
{'body': 'la la $$fixes-98765$$ ha ha', 'user': JUJUBOT_USER}]
213
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
214
code, reason = check_blockers.get_reason(bugs, args)
215
self.assertEqual(1, code)
216
self.assertEqual("Does not match ['fixes-98765']", reason)
218
def test_get_reason_with_blockers_with_reply_jujubot_comment(self):
219
args = check_blockers.parse_args(['check', 'master', '17'])
220
with patch('check_blockers.get_json') as gj:
222
{'body': '$$merge$$', 'user': OTHER_USER},
223
{'body': 'Juju bot wrote $$fixes-98765$$', 'user': OTHER_USER}]
224
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
225
code, reason = check_blockers.get_reason(bugs, args)
226
self.assertEqual(1, code)
227
self.assertEqual("Does not match ['fixes-98765']", reason)
229
def test_get_reason_with_blockers_with_jfdi(self):
230
args = check_blockers.parse_args(['check', 'master', '17'])
231
with patch('check_blockers.get_json') as gj:
233
{'body': '$$merge$$', 'user': OTHER_USER},
234
{'body': 'la la __JFDI__ ha ha', 'user': OTHER_USER}]
235
bugs = {'98765': {'self_link': 'https://lp/j/98765'}}
236
code, reason = check_blockers.get_reason(bugs, args)
237
self.assertEqual(0, code)
238
self.assertEqual("Engineer says JFDI", reason)
240
def test_get_json(self):
242
response.getcode.return_value = 200
243
response.read.side_effect = ['{"result": []}']
244
with patch('check_blockers.urllib2.urlopen') as urlopen:
245
urlopen.return_value = response
246
json = check_blockers.get_json("http://api.testing/")
247
request = urlopen.call_args[0][0]
248
self.assertEqual(request.get_full_url(), "http://api.testing/")
249
self.assertEqual(request.get_header("Cache-control"),
250
"max-age=0, must-revalidate")
251
self.assertEqual(json, {"result": []})
253
def test_update_bugs(self):
254
lp = make_fake_lp(series=False, bugs=True)
255
bugs = check_blockers.get_lp_bugs(lp, 'master', ['blocker'])
256
code, changes = check_blockers.update_bugs(
257
bugs, 'master', '1234', dry_run=False)
258
self.assertEqual(0, code)
259
self.assertIn('Updated two', changes)
260
self.assertEqual('Fix Released', bugs['54321'].status)
261
self.assertEqual(1, bugs['54321'].lp_save.call_count)
262
expected_subject = 'Fix Released in juju-core master'
264
'Juju-CI verified that this issue is %s:\n'
265
' http://reports.vapour.ws/releases/1234' % expected_subject)
266
bugs['54321'].bug.newMessage.assert_called_with(
267
subject=expected_subject, content=expected_content)
269
def test_update_bugs_with_dry_run(self):
270
lp = make_fake_lp(series=False, bugs=True)
271
bugs = check_blockers.get_lp_bugs(lp, 'master', ['blocker'])
272
code, changes = check_blockers.update_bugs(
273
bugs, 'master', '1234', dry_run=True)
274
self.assertEqual(0, bugs['54321'].lp_save.call_count)