예제 #1
0
    def test_is_first_fix_any_any(self):
        tr = '4.8.0'
        bug_a = BugzillaBug(flexmock(
            id=1,
            keywords=constants.TRACKER_BUG_KEYWORDS,
            whiteboard='component:runc',
            product=constants.BUGZILLA_PRODUCT_OCP,
            target_release=['4.7.z'],
            status='RELEASE_PENDING'))
        bug_b = BugzillaBug(flexmock(
            id=2,
            keywords=constants.TRACKER_BUG_KEYWORDS,
            whiteboard='component:runc',
            product=constants.BUGZILLA_PRODUCT_OCP,
            target_release=[tr],
            status='ON_QA'))
        bug_c = BugzillaBug(flexmock(
            id=3,
            keywords=constants.TRACKER_BUG_KEYWORDS,
            whiteboard='component:crio',
            product=constants.BUGZILLA_PRODUCT_OCP,
            target_release=[tr],
            status='ON_QA'))
        tracker_bug_objs = [bug_a, bug_b, bug_c]
        tracker_bug_ids = [t.id for t in tracker_bug_objs]
        flaw_bug = BugzillaBug(flexmock(id=4, depends_on=tracker_bug_ids))

        flexmock(BugzillaBugTracker).should_receive("login")
        bug_tracker = BugzillaBugTracker({})
        bug_tracker.should_receive("get_bugs").with_args(tracker_bug_ids).and_return(tracker_bug_objs)

        expected = True
        actual = bzutil.is_first_fix_any(bug_tracker, flaw_bug, tr)
        self.assertEqual(expected, actual)
예제 #2
0
 def bug_trackers(self):
     if self._bug_trackers:
         return self._bug_trackers
     if not self.only_jira:
         self._bug_trackers['bugzilla'] = BugzillaBugTracker(BugzillaBugTracker.get_config(self))
     if self.use_jira or self.only_jira:
         self._bug_trackers['jira'] = JIRABugTracker(JIRABugTracker.get_config(self))
     return self._bug_trackers
예제 #3
0
    def test_add_comment(self):
        bug = flexmock(id=123)
        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        client = flexmock()
        mock_arg = 1
        client.should_receive("build_update").with_args(comment='comment', comment_private=True)\
            .ordered().and_return(mock_arg)
        client.should_receive("update_bugs").with_args([123],
                                                       mock_arg).ordered()

        bz = BugzillaBugTracker({})
        bz._client = client
        bz.add_comment(bug.id, 'comment', private=True)
예제 #4
0
    def test_update_bug_status_with_comment(self):
        bug = flexmock(id=123, status="status1")
        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        client = flexmock()
        client.should_receive("build_update").ordered()
        client.should_receive("update_bugs").ordered()
        comment = 'Elliott changed bug status from status1 to status2.\ncomment'
        flexmock(BugzillaBugTracker).should_receive("add_comment").with_args(
            bug.id, comment, private=True, noop=False)

        bz = BugzillaBugTracker({})
        bz._client = client
        bz.update_bug_status(bug, target_status='status2', comment='comment')
예제 #5
0
    def test_update_bug_status(self):
        bug = flexmock(id=123, status="status1")
        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        client = flexmock()
        mock_arg = 1
        client.should_receive("build_update").with_args(
            status='status2').ordered().and_return(mock_arg)
        client.should_receive("update_bugs").with_args([123],
                                                       mock_arg).ordered()

        bz = BugzillaBugTracker({})
        bz._client = client
        bz.update_bug_status(bug, target_status='status2', log_comment=False)
예제 #6
0
    def test_get_corresponding_flaw_bugs_jira(self):
        product = 'Security Response'
        component = 'vulnerability'
        valid_flaw = BugzillaBug(flexmock(product=product, component=component, id=9999))
        invalid_flaw = BugzillaBug(flexmock(product=product, component='foo', id=9998))
        flaw_bugs = [valid_flaw, invalid_flaw]

        tracker_bugs = [
            JIRABug(flexmock(key='OCPBUGS-1', fields=flexmock(labels=[f"flaw:bz#{valid_flaw.id}",
                                                                      f"flaw:bz#{invalid_flaw.id}"]))),
            JIRABug(flexmock(key='OCPBUGS-2', fields=flexmock(labels=[f"flaw:bz#{invalid_flaw.id}"]))),
            JIRABug(flexmock(key='OCPBUGS-3', fields=flexmock(labels=[f"flaw:bz#{valid_flaw.id}"])))
        ]

        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        flexmock(JIRABugTracker).should_receive("login").and_return(None)
        flexmock(BugzillaBugTracker).should_receive("get_bugs").and_return(flaw_bugs)
        bug_tracker = JIRABugTracker({})
        flaw_bug_tracker = BugzillaBugTracker({})

        expected = (
            {'OCPBUGS-1': [valid_flaw.id], 'OCPBUGS-2': [], 'OCPBUGS-3': [valid_flaw.id]},
            {valid_flaw.id: valid_flaw}
        )
        actual = bug_tracker.get_corresponding_flaw_bugs(tracker_bugs, flaw_bug_tracker)
        self.assertEqual(expected, actual)
예제 #7
0
    def test_is_first_fix_any_no_valid_trackers(self):
        tr = '4.8.0'
        tracker_bug_ids = [1, 2]
        bug_a = BugzillaBug(flexmock(
            id=1,
            product=constants.BUGZILLA_PRODUCT_OCP,
            keywords=['foo'])
        )
        tracker_bug_objs = [bug_a]
        flaw_bug = BugzillaBug(flexmock(id=6, depends_on=tracker_bug_ids))

        flexmock(BugzillaBugTracker).should_receive("login")
        bug_tracker = BugzillaBugTracker({})
        bug_tracker.should_receive("get_bugs").with_args(tracker_bug_ids).and_return(tracker_bug_objs)

        expected = True
        actual = bzutil.is_first_fix_any(bug_tracker, flaw_bug, tr)
        self.assertEqual(expected, actual)
예제 #8
0
 def test_get_config(self):
     config = {'foo': 1, 'bugzilla_config': {'bar': 2}}
     runtime = flexmock(
         gitdata=flexmock(load_data=flexmock(data=config)),
         get_major_minor=lambda: (4, 9)
     )
     actual = BugzillaBugTracker.get_config(runtime)
     expected = {'foo': 1, 'bar': 2}
     self.assertEqual(actual, expected)
예제 #9
0
    def test_is_first_fix_any_missing_whiteboard_component(self):
        tr = '4.8.0'
        tracker_bug_ids = [1, 2]
        bug_a = BugzillaBug(flexmock(
            id=1,
            product=constants.BUGZILLA_PRODUCT_OCP,
            keywords=constants.TRACKER_BUG_KEYWORDS,
            whiteboard='', target_release=[tr]
        ))
        tracker_bug_objs = [bug_a]
        flaw_bug = BugzillaBug(flexmock(id=6, depends_on=tracker_bug_ids))

        flexmock(BugzillaBugTracker).should_receive("login")
        bug_tracker = BugzillaBugTracker({})
        bug_tracker.should_receive("get_bugs").with_args(tracker_bug_ids).and_return(tracker_bug_objs)

        expected = False
        actual = bzutil.is_first_fix_any(bug_tracker, flaw_bug, tr)
        self.assertEqual(expected, actual)
예제 #10
0
    def test_get_corresponding_flaw_bugs_bz(self):
        product = 'Security Response'
        component = 'vulnerability'
        valid_flaw_a = BugzillaBug(flexmock(product=product, component=component, id=1))
        valid_flaw_b = BugzillaBug(flexmock(product=product, component=component, id=2))
        invalid_flaw_c = BugzillaBug(flexmock(product='foo', component=component, id=3))
        invalid_flaw_d = BugzillaBug(flexmock(product=product, component='bar', id=4))
        flaw_bugs = [valid_flaw_a, valid_flaw_b]

        tracker_bugs = [
            BugzillaBug(flexmock(blocks=[valid_flaw_a.id, valid_flaw_b.id], id=10)),
            BugzillaBug(flexmock(blocks=[valid_flaw_b.id, invalid_flaw_c.id, invalid_flaw_d.id], id=11)),
        ]

        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        flexmock(BugzillaBugTracker).should_receive("get_bugs").and_return(flaw_bugs)
        bug_tracker = BugzillaBugTracker({})

        expected = (
            {10: [valid_flaw_a.id, valid_flaw_b.id], 11: [valid_flaw_b.id]},
            {valid_flaw_a.id: valid_flaw_a, valid_flaw_b.id: valid_flaw_b}
        )
        actual = bug_tracker.get_corresponding_flaw_bugs(tracker_bugs)
        self.assertEqual(expected, actual)
예제 #11
0
 def test_find_bugs_mode_search(self, mock_search: MagicMock,
                                mock_login: MagicMock):
     config = {
         'target_release': ['4.3.0', '4.3.z'],
         'product': "product",
         'server': "server"
     }
     bug_tracker = BugzillaBugTracker(config)
     find_bugs = FindBugsMode(status=['foo', 'bar'])
     find_bugs.include_status(['alpha'])
     find_bugs.exclude_status(['foo'])
     bugs = find_bugs.search(bug_tracker_obj=bug_tracker)
     self.assertEqual([1, 2], bugs)
     mock_search.assert_called_once_with(bug_tracker, {'bar', 'alpha'},
                                         verbose=False)
예제 #12
0
    def test_get_corresponding_flaw_bugs_bz_strict(self):
        tracker_bugs = [
            BugzillaBug(flexmock(blocks=[1, 2], id=10)),
            BugzillaBug(flexmock(blocks=[2, 3], id=11)),
            BugzillaBug(flexmock(blocks=[], id=12))
        ]
        product = 'Security Response'
        component = 'vulnerability'
        bug_a = BugzillaBug(flexmock(product=product, component='wrong_component', id=1))
        bug_b = BugzillaBug(flexmock(product='wrong_product', component=component, id=2))
        bug_c = BugzillaBug(flexmock(product=product, component=component, id=3))
        flaw_bugs = [bug_a, bug_b, bug_c]

        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)
        flexmock(BugzillaBugTracker).should_receive("get_bugs").and_return(flaw_bugs)
        bug_tracker = BugzillaBugTracker({})

        self.assertRaisesRegex(
            exceptions.ElliottFatalError,
            r'^No flaw bugs could be found for these trackers: {10, 12}$',
            bug_tracker.get_corresponding_flaw_bugs,
            tracker_bugs, strict=True)
예제 #13
0
def create_cli(ctx, runtime, errata_type, kind, impetus, date, assigned_to,
               manager, package_owner, with_placeholder, with_liveid, yes,
               bugs):
    """Create a new advisory. The kind of advisory must be specified with
'--kind'. Valid choices are 'rpm' and 'image'.

    You MUST specify a group (ex: "openshift-3.9") manually using the
    --group option. See examples below.

You must set a Release Date by providing a YYYY-Mon-DD formatted string to the
--date option.

The default behavior for this command is to show what the generated
advisory would look like. The raw JSON used to create the advisory
will be printed to the screen instead of posted to the Errata Tool
API.

The impetus option only affects the metadata added to the new
advisory and its synopsis.

The --assigned-to, --manager and --package-owner options are required.
They are the email addresses of the parties responsible for managing and
approving the advisory.

Adding a list of bug ids with one or more --bugs arguments attaches those bugs to the
advisory on creation.

Provide the '--yes' or '-y' option to confirm creation of the
advisory.

    PREVIEW an RPM Advisory 21 days from now (the default release date) for OSE 3.9:

    $ elliott --group openshift-3.9 create

    CREATE Image Advisory for the 3.5 series on the first Monday in March:

\b
    $ elliott --group openshift-3.5 create --yes -k image --date 2018-Mar-05
"""
    runtime.initialize()

    et_data = runtime.gitdata.load_data(key='erratatool').data

    # User entered a valid value for --date, set the release date
    release_date = datetime.datetime.strptime(date, YMD)

    ######################################################################

    unique_bugs = set(bugs)

    if bugs:
        bug_tracker = BugzillaBugTracker(
            BugzillaBugTracker.get_config(runtime))
        LOGGER.info("Fetching bugs {} from Bugzilla...".format(" ".join(
            map(str, bugs))))
        bug_objects = bug_tracker.get_bugs(bugs)
        # assert bugs are viable for a new advisory.
        _assert_bugs_are_viable(bugs, bug_objects)

    ######################################################################

    try:
        erratum = elliottlib.errata.new_erratum(
            et_data,
            errata_type=errata_type,
            kind=kind,
            boilerplate_name=(impetus if impetus != "standard" else kind),
            release_date=release_date.strftime(YMD),
            assigned_to=assigned_to,
            manager=manager,
            package_owner=package_owner)
    except elliottlib.exceptions.ErrataToolUnauthorizedException:
        exit_unauthorized()
    except elliottlib.exceptions.ErrataToolError as ex:
        raise ElliottFatalError(getattr(ex, 'message', repr(ex)))

    erratum.addBugs(unique_bugs)

    if yes:
        erratum.commit()
        green_prefix("Created new advisory: ")
        click.echo(str(erratum))

        # This is a little strange, I grant you that. For reference you
        # may wish to review the click docs
        #
        # http://click.pocoo.org/5/advanced/#invoking-other-commands
        #
        # You may be thinking, "But, add_metadata doesn't take keyword
        # arguments!" and that would be correct. However, we're not
        # calling that function directly. We actually use the context
        # 'invoke' method to call the _command_ (remember, it's wrapped
        # with click to create a 'command'). 'invoke' ensures the correct
        # options/arguments are mapped to the right parameters.
        ctx.invoke(add_metadata_cli,
                   kind=kind,
                   impetus=impetus,
                   advisory=erratum.errata_id)
        click.echo(str(erratum))

        if with_placeholder:
            click.echo("Creating and attaching placeholder bug...")
            ctx.invoke(create_placeholder_cli,
                       kind=kind,
                       advisory=erratum.errata_id)

        if with_liveid:
            click.echo("Requesting Live ID...")
            base_url = "https://errata.devel.redhat.com/errata/set_live_advisory_name"
            cmd_assert(
                f"curl -X POST --fail --negotiate -u : {base_url}/{erratum.errata_id}",
                retries=3,
                pollrate=10,
            )

    else:
        green_prefix("Would have created advisory: ")
        click.echo("")
        click.echo(erratum)
예제 #14
0
    def test_update_bug_status_same(self):
        bug = flexmock(id=123, status="status1")
        flexmock(BugzillaBugTracker).should_receive("login").and_return(None)

        bz = BugzillaBugTracker({})
        bz.update_bug_status(bug, target_status='status1')
예제 #15
0
def repair_bugs_cli(runtime, advisory, auto, id, original_state, new_state,
                    comment, close_placeholder, noop, default_advisory_type):
    """Move bugs attached to the advisory from one state to another
state. This is useful if the bugs have changed states *after* they
were attached. Similar to `find-bugs` but in reverse. `repair-bugs`
begins by reading bugs from an advisory, whereas `find-bugs` reads
from bugzilla.

This looks at attached bugs in the provided --from state and moves
them to the provided --to state.

\b
    Background: This is intended for bugs which went to MODIFIED, were
    attached to advisories, set to ON_QA, and then failed
    testing. When this happens their state is reset back to ASSIGNED.

Using --use-default-advisory without a value set for the matching key
in the build-data will cause an error and elliott will exit in a
non-zero state. Most likely you will only want to use the `rpm` state,
but that could change in the future. Use of this option conflicts with
providing an advisory with the -a/--advisory option.

    Move bugs on 123456 FROM the MODIFIED state back TO ON_QA state:

\b
    $ elliott --group=openshift-4.1 repair-bugs --auto --advisory 123456 --from MODIFIED --to ON_QA

    As above, but using the default RPM advisory defined in ocp-build-data:

\b
    $ elliott --group=openshift-4.1 repair-bugs --auto --use-default-advisory rpm --from MODIFIED --to ON_QA

    The previous examples could also be ran like this (MODIFIED and ON_QA are both defaults):

\b
    $ elliott --group=openshift-4.1 repair-bugs --auto --use-default-advisory rpm

    Bug ids may be given manually instead of using --auto:

\b
    $ elliott --group=openshift-4.1 repair-bugs --id 170899 --id 8675309 --use-default-advisory rpm
"""
    if auto and len(id) > 0:
        raise click.BadParameter(
            "Combining the automatic and manual bug modification options is not supported"
        )

    if not auto and len(id) == 0:
        # No bugs were provided
        raise click.BadParameter(
            "If not using --auto then one or more --id's must be provided")

    if advisory and default_advisory_type:
        raise click.BadParameter(
            "Use only one of --use-default-advisory or --advisory")

    if len(id) == 0 and advisory is None and default_advisory_type is None:
        # error, no bugs, advisory, or default selected
        raise click.BadParameter(
            "No input provided: Must use one of --id, --advisory, or --use-default-advisory"
        )

    # Load bugzilla information and get a reference to the api
    runtime.initialize()
    if runtime.use_jira:
        repair_bugs(runtime, advisory, auto, id, original_state, new_state,
                    comment, close_placeholder, True, noop,
                    default_advisory_type,
                    JIRABugTracker(JIRABugTracker.get_config(runtime)))
    repair_bugs(runtime, advisory, auto, id, original_state, new_state,
                comment, close_placeholder, False, noop, default_advisory_type,
                BugzillaBugTracker(BugzillaBugTracker.get_config(runtime)))