]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/dev/test_merge_arrow_pr.py
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / dev / test_merge_arrow_pr.py
CommitLineData
1d09f67e
TL
1#!/usr/bin/env python
2
3#
4# Licensed to the Apache Software Foundation (ASF) under one or more
5# contributor license agreements. See the NOTICE file distributed with
6# this work for additional information regarding copyright ownership.
7# The ASF licenses this file to You under the Apache License, Version 2.0
8# (the "License"); you may not use this file except in compliance with
9# the License. You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19
20from collections import namedtuple
21
22import pytest
23
24import merge_arrow_pr
25
26
27FakeIssue = namedtuple('issue', ['fields'])
28FakeFields = namedtuple('fields', ['status', 'summary', 'assignee',
29 'components', 'fixVersions'])
30FakeAssignee = namedtuple('assignee', ['displayName'])
31FakeStatus = namedtuple('status', ['name'])
32FakeComponent = namedtuple('component', ['name'])
33FakeVersion = namedtuple('version', ['name', 'raw'])
34
35RAW_VERSION_JSON = [
36 {'name': 'JS-0.4.0', 'released': False},
37 {'name': '0.11.0', 'released': False},
38 {'name': '0.12.0', 'released': False},
39 {'name': '0.10.0', 'released': True},
40 {'name': '0.9.0', 'released': True}
41]
42
43
44SOURCE_VERSIONS = [FakeVersion(raw['name'], raw)
45 for raw in RAW_VERSION_JSON]
46
47TRANSITIONS = [{'name': 'Resolve Issue', 'id': 1}]
48
49jira_id = 'ARROW-1234'
50status = FakeStatus('In Progress')
51fields = FakeFields(status, 'issue summary', FakeAssignee('groundhog'),
52 [FakeComponent('C++'), FakeComponent('Format')],
53 [])
54FAKE_ISSUE_1 = FakeIssue(fields)
55
56
57class FakeJIRA:
58
59 def __init__(self, issue=None, project_versions=None, transitions=None,
60 current_fix_versions=None):
61 self._issue = issue
62 self._project_versions = project_versions
63 self._transitions = transitions
64
65 def issue(self, jira_id):
66 return self._issue
67
68 def transitions(self, jira_id):
69 return self._transitions
70
71 def transition_issue(self, jira_id, transition_id, comment=None,
72 fixVersions=None):
73 self.captured_transition = {
74 'jira_id': jira_id,
75 'transition_id': transition_id,
76 'comment': comment,
77 'fixVersions': fixVersions
78 }
79
80 def get_candidate_fix_versions(self):
81 return SOURCE_VERSIONS, ['0.12.0']
82
83 def project_versions(self, project):
84 return self._project_versions
85
86
87class FakeCLI:
88
89 def __init__(self, responses=()):
90 self.responses = responses
91 self.position = 0
92
93 def prompt(self, prompt):
94 response = self.responses[self.position]
95 self.position += 1
96 return response
97
98 def fail(self, msg):
99 raise Exception(msg)
100
101
102def test_jira_fix_versions():
103 jira = FakeJIRA(project_versions=SOURCE_VERSIONS,
104 transitions=TRANSITIONS)
105
106 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
107 all_versions, default_versions = issue.get_candidate_fix_versions()
108 assert all_versions == SOURCE_VERSIONS
109 assert default_versions == ['0.11.0']
110
111
112def test_jira_no_suggest_patch_release():
113 versions_json = [
114 {'name': '0.11.1', 'released': False},
115 {'name': '0.12.0', 'released': False},
116 ]
117
118 versions = [FakeVersion(raw['name'], raw) for raw in versions_json]
119
120 jira = FakeJIRA(project_versions=versions, transitions=TRANSITIONS)
121 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
122 all_versions, default_versions = issue.get_candidate_fix_versions()
123 assert all_versions == versions
124 assert default_versions == ['0.12.0']
125
126
127def test_jira_parquet_no_suggest_non_cpp():
128 # ARROW-7351
129 versions_json = [
130 {'name': 'cpp-1.5.0', 'released': True},
131 {'name': 'cpp-1.6.0', 'released': False},
132 {'name': 'cpp-1.7.0', 'released': False},
133 {'name': '1.11.0', 'released': False},
134 {'name': '1.12.0', 'released': False}
135 ]
136
137 versions = [FakeVersion(raw['name'], raw)
138 for raw in versions_json]
139
140 jira = FakeJIRA(project_versions=versions, transitions=TRANSITIONS)
141 issue = merge_arrow_pr.JiraIssue(jira, 'PARQUET-1713', 'PARQUET',
142 FakeCLI())
143 all_versions, default_versions = issue.get_candidate_fix_versions()
144 assert all_versions == versions
145 assert default_versions == ['cpp-1.6.0']
146
147
148def test_jira_invalid_issue():
149 class Mock:
150
151 def issue(self, jira_id):
152 raise Exception("not found")
153
154 with pytest.raises(Exception):
155 merge_arrow_pr.JiraIssue(Mock(), 'ARROW-1234', 'ARROW', FakeCLI())
156
157
158def test_jira_resolve():
159 jira = FakeJIRA(issue=FAKE_ISSUE_1,
160 project_versions=SOURCE_VERSIONS,
161 transitions=TRANSITIONS)
162
163 my_comment = 'my comment'
164 fix_versions = [SOURCE_VERSIONS[1].raw]
165
166 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
167 issue.resolve(fix_versions, my_comment)
168
169 assert jira.captured_transition == {
170 'jira_id': 'ARROW-1234',
171 'transition_id': 1,
172 'comment': my_comment,
173 'fixVersions': fix_versions
174 }
175
176
177def test_jira_resolve_non_mainline():
178 jira = FakeJIRA(issue=FAKE_ISSUE_1,
179 project_versions=SOURCE_VERSIONS,
180 transitions=TRANSITIONS)
181
182 my_comment = 'my comment'
183 fix_versions = [SOURCE_VERSIONS[0].raw]
184
185 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
186 issue.resolve(fix_versions, my_comment)
187
188 assert jira.captured_transition == {
189 'jira_id': 'ARROW-1234',
190 'transition_id': 1,
191 'comment': my_comment,
192 'fixVersions': fix_versions
193 }
194
195
196def test_jira_resolve_released_fix_version():
197 # ARROW-5083
198 jira = FakeJIRA(issue=FAKE_ISSUE_1,
199 project_versions=SOURCE_VERSIONS,
200 transitions=TRANSITIONS)
201
202 cmd = FakeCLI(responses=['0.9.0'])
203 fix_versions_json = merge_arrow_pr.prompt_for_fix_version(cmd, jira)
204 assert fix_versions_json == [RAW_VERSION_JSON[-1]]
205
206
207def test_multiple_authors_bad_input():
208 a0 = 'Jimbob Crawfish <jimbob.crawfish@gmail.com>'
209 a1 = 'Jarvis McCratchett <jarvis.mccratchett@hotmail.com>'
210 a2 = 'Hank Miller <hank.miller@protonmail.com>'
211 distinct_authors = [a0, a1]
212
213 cmd = FakeCLI(responses=[''])
214 primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
215 cmd, distinct_authors)
216 assert primary_author == a0
217 assert new_distinct_authors == [a0, a1]
218
219 cmd = FakeCLI(responses=['oops', a1])
220 primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
221 cmd, distinct_authors)
222 assert primary_author == a1
223 assert new_distinct_authors == [a1, a0]
224
225 cmd = FakeCLI(responses=[a2])
226 primary_author, new_distinct_authors = merge_arrow_pr.get_primary_author(
227 cmd, distinct_authors)
228 assert primary_author == a2
229 assert new_distinct_authors == [a2, a0, a1]
230
231
232def test_jira_already_resolved():
233 status = FakeStatus('Resolved')
234 fields = FakeFields(status, 'issue summary', FakeAssignee('groundhog'),
235 [FakeComponent('Java')], [])
236 issue = FakeIssue(fields)
237
238 jira = FakeJIRA(issue=issue,
239 project_versions=SOURCE_VERSIONS,
240 transitions=TRANSITIONS)
241
242 fix_versions = [SOURCE_VERSIONS[0].raw]
243 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
244
245 with pytest.raises(Exception,
246 match="ARROW-1234 already has status 'Resolved'"):
247 issue.resolve(fix_versions, "")
248
249
250def test_no_unset_point_release_fix_version():
251 # ARROW-6915: We have had the problem of issues marked with a point release
252 # having their fix versions overwritten by the merge tool. This verifies
253 # that existing patch release versions are carried over
254 status = FakeStatus('In Progress')
255
256 versions_json = {
257 '0.14.2': {'name': '0.14.2', 'id': 1},
258 '0.15.1': {'name': '0.15.1', 'id': 2},
259 '0.16.0': {'name': '0.16.0', 'id': 3},
260 '0.17.0': {'name': '0.17.0', 'id': 4}
261 }
262
263 fields = FakeFields(status, 'summary', FakeAssignee('someone'),
264 [FakeComponent('Java')],
265 [FakeVersion(v, versions_json[v])
266 for v in ['0.17.0', '0.15.1', '0.14.2']])
267 issue = FakeIssue(fields)
268
269 jira = FakeJIRA(issue=issue, project_versions=SOURCE_VERSIONS,
270 transitions=TRANSITIONS)
271
272 issue = merge_arrow_pr.JiraIssue(jira, 'ARROW-1234', 'ARROW', FakeCLI())
273 issue.resolve([versions_json['0.16.0']], "a comment")
274
275 assert jira.captured_transition == {
276 'jira_id': 'ARROW-1234',
277 'transition_id': 1,
278 'comment': 'a comment',
279 'fixVersions': [versions_json[v]
280 for v in ['0.16.0', '0.15.1', '0.14.2']]
281 }
282
283 issue.resolve([versions_json['0.15.1']], "a comment")
284
285 assert jira.captured_transition == {
286 'jira_id': 'ARROW-1234',
287 'transition_id': 1,
288 'comment': 'a comment',
289 'fixVersions': [versions_json[v] for v in ['0.15.1', '0.14.2']]
290 }
291
292
293def test_jira_output_no_components():
294 # ARROW-5472
295 status = 'Interesting work'
296 components = []
297 output = merge_arrow_pr.format_jira_output(
298 'ARROW-1234', 'Resolved', status, FakeAssignee('Foo Bar'),
299 components)
300
301 assert output == """=== JIRA ARROW-1234 ===
302Summary\t\tInteresting work
303Assignee\tFoo Bar
304Components\tNO COMPONENTS!!!
305Status\t\tResolved
306URL\t\thttps://issues.apache.org/jira/browse/ARROW-1234"""
307
308 output = merge_arrow_pr.format_jira_output(
309 'ARROW-1234', 'Resolved', status, FakeAssignee('Foo Bar'),
310 [FakeComponent('C++'), FakeComponent('Python')])
311
312 assert output == """=== JIRA ARROW-1234 ===
313Summary\t\tInteresting work
314Assignee\tFoo Bar
315Components\tC++, Python
316Status\t\tResolved
317URL\t\thttps://issues.apache.org/jira/browse/ARROW-1234"""