os.chdir(orig_dir)
@staticmethod
- def _fake_patchwork(subpath):
+ def _fake_patchwork(url, subpath):
"""Fake Patchwork server for the function below
This handles accessing a series, providing a list consisting of a
single patch
+
+ Args:
+ url (str): URL of patchwork server
+ subpath (str): URL subpath to use
"""
re_series = re.match(r'series/(\d*)/$', subpath)
if re_series:
series = Series()
with capture_sys_output() as (_, err):
- status.collect_patches(series, 1234, self._fake_patchwork)
+ status.collect_patches(series, 1234, None, self._fake_patchwork)
self.assertIn('Warning: Patchwork reports 1 patches, series has 0',
err.getvalue())
series = Series()
series.commits = [Commit('abcd')]
- patches = status.collect_patches(series, 1234, self._fake_patchwork)
+ patches = status.collect_patches(series, 1234, None,
+ self._fake_patchwork)
self.assertEqual(1, len(patches))
patch = patches[0]
self.assertEqual('1', patch.id)
"Cannot find commit for patch 3 ('Subject 2')"],
warnings)
- def _fake_patchwork2(self, subpath):
+ def _fake_patchwork2(self, url, subpath):
"""Fake Patchwork server for the function below
This handles accessing series, patches and comments, providing the data
in self.patches to the caller
+
+ Args:
+ url (str): URL of patchwork server
+ subpath (str): URL subpath to use
"""
re_series = re.match(r'series/(\d*)/$', subpath)
re_patch = re.match(r'patches/(\d*)/$', subpath)
# Check that the tags are picked up on the first patch
status.find_new_responses(new_rtag_list, review_list, 0, commit1,
- patch1, self._fake_patchwork2)
+ patch1, None, self._fake_patchwork2)
self.assertEqual(new_rtag_list[0], {'Reviewed-by': {self.joe}})
# Now the second patch
status.find_new_responses(new_rtag_list, review_list, 1, commit2,
- patch2, self._fake_patchwork2)
+ patch2, None, self._fake_patchwork2)
self.assertEqual(new_rtag_list[1], {
'Reviewed-by': {self.mary, self.fred},
'Tested-by': {self.leb}})
new_rtag_list = [None] * count
commit1.rtags = {'Reviewed-by': {self.joe}}
status.find_new_responses(new_rtag_list, review_list, 0, commit1,
- patch1, self._fake_patchwork2)
+ patch1, None, self._fake_patchwork2)
self.assertEqual(new_rtag_list[0], {})
# For the second commit, add Ed and Fred, so only Mary should be left
'Tested-by': {self.leb},
'Reviewed-by': {self.fred}}
status.find_new_responses(new_rtag_list, review_list, 1, commit2,
- patch2, self._fake_patchwork2)
+ patch2, None, self._fake_patchwork2)
self.assertEqual(new_rtag_list[1], {'Reviewed-by': {self.mary}})
# Check that the output patches expectations:
series.commits = [commit1, commit2]
terminal.SetPrintTestMode()
status.check_patchwork_status(series, '1234', None, None, False, False,
- self._fake_patchwork2)
+ None, self._fake_patchwork2)
lines = iter(terminal.GetPrintTestLines())
col = terminal.Color()
self.assertEqual(terminal.PrintLine(' 1 Subject 1', col.BLUE),
'1 new response available in patchwork (use -d to write them to a new branch)',
None), next(lines))
- def _fake_patchwork3(self, subpath):
+ def _fake_patchwork3(self, url, subpath):
"""Fake Patchwork server for the function below
This handles accessing series, patches and comments, providing the data
in self.patches to the caller
+
+ Args:
+ url (str): URL of patchwork server
+ subpath (str): URL subpath to use
"""
re_series = re.match(r'series/(\d*)/$', subpath)
re_patch = re.match(r'patches/(\d*)/$', subpath)
terminal.SetPrintTestMode()
status.check_patchwork_status(series, '1234', branch, dest_branch,
- False, False, self._fake_patchwork3, repo)
+ False, False, None, self._fake_patchwork3,
+ repo)
lines = terminal.GetPrintTestLines()
self.assertEqual(12, len(lines))
self.assertEqual(
series.commits = [commit1, commit2]
terminal.SetPrintTestMode()
status.check_patchwork_status(series, '1234', None, None, False, True,
- self._fake_patchwork2)
+ None, self._fake_patchwork2)
lines = iter(terminal.GetPrintTestLines())
col = terminal.Color()
self.assertEqual(terminal.PrintLine(' 1 Subject 1', col.BLUE),
return patch_for_commit, commit_for_patch, warnings
-def call_rest_api(subpath):
+def call_rest_api(url, subpath):
"""Call the patchwork API and return the result as JSON
Args:
+ url (str): URL of patchwork server, e.g. 'https://patchwork.ozlabs.org'
subpath (str): URL subpath to use
Returns:
Raises:
ValueError: the URL could not be read
"""
- url = 'https://patchwork.ozlabs.org/api/1.2/%s' % subpath
- response = requests.get(url)
+ full_url = '%s/api/1.2/%s' % (url, subpath)
+ response = requests.get(full_url)
if response.status_code != 200:
- raise ValueError("Could not read URL '%s'" % url)
+ raise ValueError("Could not read URL '%s'" % full_url)
return response.json()
-def collect_patches(series, series_id, rest_api=call_rest_api):
+def collect_patches(series, series_id, url, rest_api=call_rest_api):
"""Collect patch information about a series from patchwork
Uses the Patchwork REST API to collect information provided by patchwork
series (Series): Series object corresponding to the local branch
containing the series
series_id (str): Patch series ID number
+ url (str): URL of patchwork server, e.g. 'https://patchwork.ozlabs.org'
rest_api (function): API function to call to access Patchwork, for
testing
ValueError: if the URL could not be read or the web page does not follow
the expected structure
"""
- data = rest_api('series/%s/' % series_id)
+ data = rest_api(url, 'series/%s/' % series_id)
# Get all the rows, which are patches
patch_dict = data['patches']
patches = sorted(patches, key=lambda x: x.seq)
return patches
-def find_new_responses(new_rtag_list, review_list, seq, cmt, patch,
+def find_new_responses(new_rtag_list, review_list, seq, cmt, patch, url,
rest_api=call_rest_api):
"""Find new rtags collected by patchwork that we don't know about
seq (int): Position in new_rtag_list to update
cmt (Commit): Commit object for this commit
patch (Patch): Corresponding Patch object for this patch
+ url (str): URL of patchwork server, e.g. 'https://patchwork.ozlabs.org'
rest_api (function): API function to call to access Patchwork, for
testing
"""
return
# Get the content for the patch email itself as well as all comments
- data = rest_api('patches/%s/' % patch.id)
+ data = rest_api(url, 'patches/%s/' % patch.id)
pstrm = PatchStream.process_text(data['content'], True)
rtags = collections.defaultdict(set)
for response, people in pstrm.commit.rtags.items():
rtags[response].update(people)
- data = rest_api('patches/%s/comments/' % patch.id)
+ data = rest_api(url, 'patches/%s/comments/' % patch.id)
reviews = []
for comment in data:
return num_added
def check_patchwork_status(series, series_id, branch, dest_branch, force,
- show_comments, rest_api=call_rest_api,
+ show_comments, url, rest_api=call_rest_api,
test_repo=None):
"""Check the status of a series on Patchwork
dest_branch (str): Name of new branch to create, or None
force (bool): True to force overwriting dest_branch if it exists
show_comments (bool): True to show the comments on each patch
+ url (str): URL of patchwork server, e.g. 'https://patchwork.ozlabs.org'
rest_api (function): API function to call to access Patchwork, for
testing
test_repo (pygit2.Repository): Repo to use (use None unless testing)
"""
- patches = collect_patches(series, series_id, rest_api)
+ patches = collect_patches(series, series_id, url, rest_api)
col = terminal.Color()
count = len(series.commits)
new_rtag_list = [None] * count
with concurrent.futures.ThreadPoolExecutor(max_workers=16) as executor:
futures = executor.map(
find_new_responses, repeat(new_rtag_list), repeat(review_list),
- range(count), series.commits, patch_list, repeat(rest_api))
+ range(count), series.commits, patch_list, repeat(url),
+ repeat(rest_api))
for fresponse in futures:
if fresponse:
raise fresponse.exception()