mirror of
https://github.com/rpm-software-management/tito.git
synced 2025-02-23 12:12:47 +00:00
Move bugzilla code to a separate file
Fix #358 Previously the bugzilla-specific code was implemented in `tito.common` which is imported from everywhere. Therefore missing dependency to `python3-bugzilla` resulted in failure even for simple commands such as `tito build --tgz`.
This commit is contained in:
parent
6e1ebf4a3f
commit
3a62bb6613
6 changed files with 347 additions and 339 deletions
124
src/tito/bugtracker.py
Normal file
124
src/tito/bugtracker.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
import os
|
||||
import re
|
||||
from bugzilla.rhbugzilla import RHBugzilla
|
||||
from tito.common import debug, error_out
|
||||
from tito.exception import TitoException
|
||||
from tito.compat import xmlrpclib
|
||||
|
||||
|
||||
class MissingBugzillaCredsException(TitoException):
|
||||
pass
|
||||
|
||||
|
||||
class BugzillaExtractor(object):
|
||||
"""
|
||||
Parses output of a dist-git commit diff looking for changelog
|
||||
entries that look like they reference bugzilla commits.
|
||||
|
||||
Optionally can check bugzilla for required flags on each bug.
|
||||
"""
|
||||
def __init__(self, diff_output, required_flags=None,
|
||||
placeholder_bz=None):
|
||||
|
||||
self.diff_output = diff_output
|
||||
self.required_flags = required_flags
|
||||
self.placeholder_bz = placeholder_bz
|
||||
|
||||
# Tuples of bugzilla ID + commit message we extracted:
|
||||
self.bzs = []
|
||||
|
||||
def extract(self):
|
||||
|
||||
self.bzs = self._extract_bzs()
|
||||
|
||||
if self.required_flags:
|
||||
self._check_for_bugzilla_creds()
|
||||
self.bzs = self._filter_bzs_with_flags()
|
||||
|
||||
return self._format_lines()
|
||||
|
||||
def _check_for_bugzilla_creds(self):
|
||||
if not os.path.exists(os.path.expanduser("~/.bugzillarc")):
|
||||
raise MissingBugzillaCredsException("Missing ~/.bugzillarc")
|
||||
else:
|
||||
debug("Found bugzilla credentials in ~/.bugzillarc")
|
||||
|
||||
def _extract_bzs(self):
|
||||
"""
|
||||
Parses the output of CVS diff or a series of git commit log entries,
|
||||
looking for new lines which look like a commit of the format:
|
||||
|
||||
######: Commit message
|
||||
|
||||
Returns a list of lines of text similar to:
|
||||
|
||||
Resolves: #XXXXXX - Commit message
|
||||
|
||||
If the releaser specifies any required bugzilla flags we will
|
||||
check each bug found and see if it has all required flags. If not
|
||||
we skip it. If we end up with *no* bugs with the required flags
|
||||
our build is likely to fail, so we look for a placeholder bugzilla
|
||||
defined in relaser config and use that instead if possible, otherwise
|
||||
error out.
|
||||
|
||||
Returns a list of lines to write to the commit message as is.
|
||||
"""
|
||||
regex = re.compile(r"^- (\d*)\s?[:-]+\s?(.*)")
|
||||
diff_regex = re.compile(r"^(\+- )+(\d*)\s?[:-]+\s?(.*)")
|
||||
bzs = []
|
||||
for line in self.diff_output.split("\n"):
|
||||
match = re.match(regex, line)
|
||||
match2 = re.match(diff_regex, line)
|
||||
if match:
|
||||
bzs.append((match.group(1), match.group(2)))
|
||||
elif match2:
|
||||
bzs.append((match2.group(2), match2.group(3)))
|
||||
return bzs
|
||||
|
||||
def _format_lines(self):
|
||||
output = []
|
||||
for bz in self.bzs:
|
||||
output.append("Resolves: #%s - %s" % (bz[0], bz[1]))
|
||||
if len(output) == 0 and self.required_flags:
|
||||
# No bugzillas had required flags, use a placeholder if
|
||||
# we have one, otherwise we have to error out.
|
||||
if self.placeholder_bz:
|
||||
print("No bugs with required flags were found, using placeholder: %s" % self.placeholder_bz)
|
||||
output.append("Related: #%s" % self.placeholder_bz)
|
||||
else:
|
||||
error_out("No bugzillas found with required flags: %s" %
|
||||
self.required_flags)
|
||||
return output
|
||||
|
||||
def _filter_bzs_with_flags(self):
|
||||
print("Checking flags on bugs: %s" % self.bzs)
|
||||
print(" required flags: %s" % self.required_flags)
|
||||
|
||||
# TODO: Would be nice to load bugs in bulk here but for now we'll
|
||||
# keep it simple.
|
||||
filtered_bzs = []
|
||||
for bz_tuple in self.bzs:
|
||||
bug_id = bz_tuple[0]
|
||||
try:
|
||||
bug = self._load_bug(bug_id)
|
||||
except xmlrpclib.Fault:
|
||||
print("WARNING: Bug %s does not seem to exist." % bug_id)
|
||||
continue
|
||||
debug("Bug %s has flags: %s" % (bug_id, bug.flags))
|
||||
flags_missing = False
|
||||
for flag in self.required_flags:
|
||||
if bug.get_flag_status(flag[0:-1]) != flag[-1]:
|
||||
print("WARNING: Bug %s missing required flag: %s" %
|
||||
(bug_id, flag))
|
||||
flags_missing = True
|
||||
break
|
||||
else:
|
||||
debug("Bug %s has required flag: %s" %
|
||||
(bug_id, flag))
|
||||
if not flags_missing:
|
||||
filtered_bzs.append(bz_tuple)
|
||||
return filtered_bzs
|
||||
|
||||
def _load_bug(self, bug_id):
|
||||
bugzilla = RHBugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi')
|
||||
return bugzilla.getbug(bug_id, include_fields=['id', 'flags'])
|
|
@ -30,10 +30,7 @@ import tempfile
|
|||
|
||||
from blessed import Terminal
|
||||
|
||||
from bugzilla.rhbugzilla import RHBugzilla
|
||||
|
||||
from tito.compat import xmlrpclib, getstatusoutput
|
||||
from tito.exception import TitoException
|
||||
from tito.compat import getstatusoutput
|
||||
from tito.exception import RunCommandException
|
||||
from tito.tar import TarFixer
|
||||
|
||||
|
@ -89,124 +86,6 @@ def extract_sources(spec_file_lines):
|
|||
return filenames
|
||||
|
||||
|
||||
class MissingBugzillaCredsException(TitoException):
|
||||
pass
|
||||
|
||||
|
||||
class BugzillaExtractor(object):
|
||||
"""
|
||||
Parses output of a dist-git commit diff looking for changelog
|
||||
entries that look like they reference bugzilla commits.
|
||||
|
||||
Optionally can check bugzilla for required flags on each bug.
|
||||
"""
|
||||
def __init__(self, diff_output, required_flags=None,
|
||||
placeholder_bz=None):
|
||||
|
||||
self.diff_output = diff_output
|
||||
self.required_flags = required_flags
|
||||
self.placeholder_bz = placeholder_bz
|
||||
|
||||
# Tuples of bugzilla ID + commit message we extracted:
|
||||
self.bzs = []
|
||||
|
||||
def extract(self):
|
||||
|
||||
self.bzs = self._extract_bzs()
|
||||
|
||||
if self.required_flags:
|
||||
self._check_for_bugzilla_creds()
|
||||
self.bzs = self._filter_bzs_with_flags()
|
||||
|
||||
return self._format_lines()
|
||||
|
||||
def _check_for_bugzilla_creds(self):
|
||||
if not os.path.exists(os.path.expanduser("~/.bugzillarc")):
|
||||
raise MissingBugzillaCredsException("Missing ~/.bugzillarc")
|
||||
else:
|
||||
debug("Found bugzilla credentials in ~/.bugzillarc")
|
||||
|
||||
def _extract_bzs(self):
|
||||
"""
|
||||
Parses the output of CVS diff or a series of git commit log entries,
|
||||
looking for new lines which look like a commit of the format:
|
||||
|
||||
######: Commit message
|
||||
|
||||
Returns a list of lines of text similar to:
|
||||
|
||||
Resolves: #XXXXXX - Commit message
|
||||
|
||||
If the releaser specifies any required bugzilla flags we will
|
||||
check each bug found and see if it has all required flags. If not
|
||||
we skip it. If we end up with *no* bugs with the required flags
|
||||
our build is likely to fail, so we look for a placeholder bugzilla
|
||||
defined in relaser config and use that instead if possible, otherwise
|
||||
error out.
|
||||
|
||||
Returns a list of lines to write to the commit message as is.
|
||||
"""
|
||||
regex = re.compile(r"^- (\d*)\s?[:-]+\s?(.*)")
|
||||
diff_regex = re.compile(r"^(\+- )+(\d*)\s?[:-]+\s?(.*)")
|
||||
bzs = []
|
||||
for line in self.diff_output.split("\n"):
|
||||
match = re.match(regex, line)
|
||||
match2 = re.match(diff_regex, line)
|
||||
if match:
|
||||
bzs.append((match.group(1), match.group(2)))
|
||||
elif match2:
|
||||
bzs.append((match2.group(2), match2.group(3)))
|
||||
return bzs
|
||||
|
||||
def _format_lines(self):
|
||||
output = []
|
||||
for bz in self.bzs:
|
||||
output.append("Resolves: #%s - %s" % (bz[0], bz[1]))
|
||||
if len(output) == 0 and self.required_flags:
|
||||
# No bugzillas had required flags, use a placeholder if
|
||||
# we have one, otherwise we have to error out.
|
||||
if self.placeholder_bz:
|
||||
print("No bugs with required flags were found, using placeholder: %s" % self.placeholder_bz)
|
||||
output.append("Related: #%s" % self.placeholder_bz)
|
||||
else:
|
||||
error_out("No bugzillas found with required flags: %s" %
|
||||
self.required_flags)
|
||||
return output
|
||||
|
||||
def _filter_bzs_with_flags(self):
|
||||
print("Checking flags on bugs: %s" % self.bzs)
|
||||
print(" required flags: %s" % self.required_flags)
|
||||
|
||||
# TODO: Would be nice to load bugs in bulk here but for now we'll
|
||||
# keep it simple.
|
||||
filtered_bzs = []
|
||||
for bz_tuple in self.bzs:
|
||||
bug_id = bz_tuple[0]
|
||||
try:
|
||||
bug = self._load_bug(bug_id)
|
||||
except xmlrpclib.Fault:
|
||||
print("WARNING: Bug %s does not seem to exist." % bug_id)
|
||||
continue
|
||||
debug("Bug %s has flags: %s" % (bug_id, bug.flags))
|
||||
flags_missing = False
|
||||
for flag in self.required_flags:
|
||||
if bug.get_flag_status(flag[0:-1]) != flag[-1]:
|
||||
print("WARNING: Bug %s missing required flag: %s" %
|
||||
(bug_id, flag))
|
||||
flags_missing = True
|
||||
break
|
||||
else:
|
||||
debug("Bug %s has required flag: %s" %
|
||||
(bug_id, flag))
|
||||
if not flags_missing:
|
||||
filtered_bzs.append(bz_tuple)
|
||||
return filtered_bzs
|
||||
|
||||
def _load_bug(self, bug_id):
|
||||
bugzilla = RHBugzilla(url='https://bugzilla.redhat.com/xmlrpc.cgi')
|
||||
return bugzilla.getbug(bug_id, include_fields=['id', 'flags'])
|
||||
|
||||
|
||||
def _out(msgs, prefix, color_func, stream=sys.stdout):
|
||||
if prefix is None:
|
||||
fmt = "%(msg)s"
|
||||
|
|
|
@ -16,13 +16,14 @@ import subprocess
|
|||
import sys
|
||||
import tempfile
|
||||
|
||||
from tito.common import run_command, BugzillaExtractor, debug, extract_sources, \
|
||||
MissingBugzillaCredsException, error_out, chdir, warn_out, info_out, find_mead_chain_file
|
||||
from tito.common import run_command, debug, extract_sources, \
|
||||
error_out, chdir, warn_out, info_out, find_mead_chain_file
|
||||
from tito.compat import getoutput, getstatusoutput, write
|
||||
from tito.release import Releaser
|
||||
from tito.release.main import PROTECTED_BUILD_SYS_FILES
|
||||
from tito.buildparser import BuildTargetParser
|
||||
from tito.exception import RunCommandException
|
||||
from tito.bugtracker import BugzillaExtractor, MissingBugzillaCredsException
|
||||
import getpass
|
||||
from string import Template
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@ import tempfile
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
from tito.common import run_command, debug, BugzillaExtractor
|
||||
from tito.common import run_command, debug
|
||||
from tito.compat import getoutput, write, getstatusoutput
|
||||
from tito.release.distgit import FedoraGitReleaser
|
||||
from tito.bugtracker import BugzillaExtractor
|
||||
|
||||
|
||||
class ObsReleaser(FedoraGitReleaser):
|
||||
|
|
216
test/unit/bugtracker_tests.py
Normal file
216
test/unit/bugtracker_tests.py
Normal file
|
@ -0,0 +1,216 @@
|
|||
import unittest
|
||||
from tito.bugtracker import BugzillaExtractor
|
||||
from mock import Mock, patch
|
||||
|
||||
|
||||
class ExtractBugzillasTest(unittest.TestCase):
|
||||
|
||||
def test_single_line(self):
|
||||
commit_log = "- 123456: Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_with_dash(self):
|
||||
commit_log = "- 123456 - Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_with_no_spaces(self):
|
||||
commit_log = "- 123456-Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_diff_format(self):
|
||||
commit_log = "+- 123456: Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_line_no_bz(self):
|
||||
commit_log = "- Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(0, len(results))
|
||||
|
||||
def test_multi_line(self):
|
||||
commit_log = "- 123456: Did something interesting.\n- Another commit.\n" \
|
||||
"- 456789: A third commit."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #456789 - A third commit.",
|
||||
results[1])
|
||||
|
||||
def test_single_required_flag_found(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(1, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_required_flags_found(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug2 = ('444555', 'Something else.')
|
||||
bug3 = ('987654', 'Such amaze!')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug2, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
bug_mocks = [
|
||||
MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']),
|
||||
MockBug(bug2[0], ['myos-2.0?', 'pm_ack?']),
|
||||
MockBug(bug3[0], ['myos-1.0+', 'pm_ack+'])]
|
||||
|
||||
def next_bug(*args):
|
||||
return bug_mocks.pop(0)
|
||||
|
||||
extractor._load_bug = Mock(side_effect=next_bug)
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(2, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
self.assertEquals(bug3[0], extractor.bzs[1][0])
|
||||
self.assertEquals(bug3[1], extractor.bzs[1][1])
|
||||
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #987654 - Such amaze!",
|
||||
results[1])
|
||||
|
||||
@patch("tito.bugtracker.error_out")
|
||||
def test_required_flags_missing(self, mock_error):
|
||||
required_flags = ['myos-2.0+']
|
||||
extractor = BugzillaExtractor("", required_flags)
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug2 = ('444555', 'Something else.')
|
||||
bug3 = ('987654', 'Such amaze!')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug2, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
bug_mocks = [
|
||||
MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']),
|
||||
MockBug(bug2[0], ['myos-2.0?', 'pm_ack?']),
|
||||
MockBug(bug3[0], ['myos-1.0+', 'pm_ack+'])]
|
||||
|
||||
def next_bug(*args):
|
||||
return bug_mocks.pop(0)
|
||||
|
||||
extractor._load_bug = Mock(side_effect=next_bug)
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
self.assertEquals(0, len(results))
|
||||
mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags)
|
||||
|
||||
def test_required_flags_missing_with_placeholder(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-2.0+'], placeholder_bz="54321")
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Related: #54321", results[0])
|
||||
|
||||
def test_same_id_multiple_times(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug3 = ('123456', 'Oops, lets try again.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(2, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
self.assertEquals(bug3[0], extractor.bzs[1][0])
|
||||
self.assertEquals(bug3[1], extractor.bzs[1][1])
|
||||
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #123456 - Oops, lets try again.",
|
||||
results[1])
|
||||
|
||||
@patch("tito.bugtracker.error_out")
|
||||
def test_bug_doesnt_exist(self, mock_error):
|
||||
required_flags = ['myos-1.0+', 'pm_ack+']
|
||||
extractor = BugzillaExtractor("", required_flags)
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
from tito.compat import xmlrpclib
|
||||
extractor._load_bug = Mock(side_effect=xmlrpclib.Fault("", ""))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
self.assertEquals(0, len(results))
|
||||
mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags)
|
||||
|
||||
|
||||
class MockBug(object):
|
||||
def __init__(self, bug_id, flags):
|
||||
self.flags = {}
|
||||
for flag in flags:
|
||||
self.flags[flag[0:-1]] = flag[-1]
|
||||
|
||||
def get_flag_status(self, flag):
|
||||
if flag in self.flags:
|
||||
return self.flags[flag]
|
||||
else:
|
||||
return None
|
|
@ -16,7 +16,7 @@
|
|||
from tito.common import (replace_version, find_spec_like_file, increase_version,
|
||||
search_for, compare_version, run_command_print, find_wrote_in_rpmbuild_output,
|
||||
render_cheetah, increase_zstream, reset_release, find_file_with_extension,
|
||||
normalize_class_name, extract_sha1, BugzillaExtractor, DEFAULT_BUILD_DIR, munge_specfile,
|
||||
normalize_class_name, extract_sha1, DEFAULT_BUILD_DIR, munge_specfile,
|
||||
munge_setup_macro, get_project_name,
|
||||
_out)
|
||||
|
||||
|
@ -496,219 +496,6 @@ class VersionMathTest(unittest.TestCase):
|
|||
self.assertEquals(expected, reset_release(line))
|
||||
|
||||
|
||||
class ExtractBugzillasTest(unittest.TestCase):
|
||||
|
||||
def test_single_line(self):
|
||||
commit_log = "- 123456: Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_with_dash(self):
|
||||
commit_log = "- 123456 - Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_with_no_spaces(self):
|
||||
commit_log = "- 123456-Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_diff_format(self):
|
||||
commit_log = "+- 123456: Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_single_line_no_bz(self):
|
||||
commit_log = "- Did something interesting."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(0, len(results))
|
||||
|
||||
def test_multi_line(self):
|
||||
commit_log = "- 123456: Did something interesting.\n- Another commit.\n" \
|
||||
"- 456789: A third commit."
|
||||
extractor = BugzillaExtractor(commit_log)
|
||||
results = extractor.extract()
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #456789 - A third commit.",
|
||||
results[1])
|
||||
|
||||
def test_single_required_flag_found(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(1, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
|
||||
def test_required_flags_found(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug2 = ('444555', 'Something else.')
|
||||
bug3 = ('987654', 'Such amaze!')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug2, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
bug_mocks = [
|
||||
MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']),
|
||||
MockBug(bug2[0], ['myos-2.0?', 'pm_ack?']),
|
||||
MockBug(bug3[0], ['myos-1.0+', 'pm_ack+'])]
|
||||
|
||||
def next_bug(*args):
|
||||
return bug_mocks.pop(0)
|
||||
|
||||
extractor._load_bug = Mock(side_effect=next_bug)
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(2, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
self.assertEquals(bug3[0], extractor.bzs[1][0])
|
||||
self.assertEquals(bug3[1], extractor.bzs[1][1])
|
||||
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #987654 - Such amaze!",
|
||||
results[1])
|
||||
|
||||
@patch("tito.common.error_out")
|
||||
def test_required_flags_missing(self, mock_error):
|
||||
required_flags = ['myos-2.0+']
|
||||
extractor = BugzillaExtractor("", required_flags)
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug2 = ('444555', 'Something else.')
|
||||
bug3 = ('987654', 'Such amaze!')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug2, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
bug_mocks = [
|
||||
MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']),
|
||||
MockBug(bug2[0], ['myos-2.0?', 'pm_ack?']),
|
||||
MockBug(bug3[0], ['myos-1.0+', 'pm_ack+'])]
|
||||
|
||||
def next_bug(*args):
|
||||
return bug_mocks.pop(0)
|
||||
|
||||
extractor._load_bug = Mock(side_effect=next_bug)
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
self.assertEquals(0, len(results))
|
||||
mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags)
|
||||
|
||||
def test_required_flags_missing_with_placeholder(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-2.0+'], placeholder_bz="54321")
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
|
||||
self.assertEquals(1, len(results))
|
||||
self.assertEquals("Related: #54321", results[0])
|
||||
|
||||
def test_same_id_multiple_times(self):
|
||||
|
||||
extractor = BugzillaExtractor("", required_flags=[
|
||||
'myos-1.0+', 'pm_ack+'])
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
bug3 = ('123456', 'Oops, lets try again.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1, bug3])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
extractor._load_bug = Mock(
|
||||
return_value=MockBug(bug1[0], ['myos-1.0+', 'pm_ack+']))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(2, len(extractor.bzs))
|
||||
self.assertEquals(bug1[0], extractor.bzs[0][0])
|
||||
self.assertEquals(bug1[1], extractor.bzs[0][1])
|
||||
self.assertEquals(bug3[0], extractor.bzs[1][0])
|
||||
self.assertEquals(bug3[1], extractor.bzs[1][1])
|
||||
|
||||
self.assertEquals(2, len(results))
|
||||
self.assertEquals("Resolves: #123456 - Did something interesting.",
|
||||
results[0])
|
||||
self.assertEquals("Resolves: #123456 - Oops, lets try again.",
|
||||
results[1])
|
||||
|
||||
@patch("tito.common.error_out")
|
||||
def test_bug_doesnt_exist(self, mock_error):
|
||||
required_flags = ['myos-1.0+', 'pm_ack+']
|
||||
extractor = BugzillaExtractor("", required_flags)
|
||||
bug1 = ('123456', 'Did something interesting.')
|
||||
extractor._extract_bzs = Mock(return_value=[
|
||||
bug1])
|
||||
extractor._check_for_bugzilla_creds = Mock()
|
||||
|
||||
from tito.compat import xmlrpclib
|
||||
extractor._load_bug = Mock(side_effect=xmlrpclib.Fault("", ""))
|
||||
|
||||
results = extractor.extract()
|
||||
|
||||
self.assertEquals(0, len(extractor.bzs))
|
||||
self.assertEquals(0, len(results))
|
||||
mock_error.assert_called_once_with("No bugzillas found with required flags: %s" % required_flags)
|
||||
|
||||
|
||||
class MockBug(object):
|
||||
def __init__(self, bug_id, flags):
|
||||
self.flags = {}
|
||||
for flag in flags:
|
||||
self.flags[flag[0:-1]] = flag[-1]
|
||||
|
||||
def get_flag_status(self, flag):
|
||||
if flag in self.flags:
|
||||
return self.flags[flag]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class MungeSetupMacroTests(unittest.TestCase):
|
||||
SOURCE = "tito-git-3.20362dd"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue