Example #1
0
 def can_test_on_upstream(self):
     change_states = {"POST", "MODIFIED"}
     # With these states, the change is in upstream
     if self.status not in {"POST", "MODIFIED", "ON_QA", "VERIFIED", "RELEASE_PENDING"}:
         return False
     history = self.get_history()["bugs"][0]["history"]
     changes = []
     # We look for status changes in the history
     for event in history:
         for change in event["changes"]:
             if change["field_name"].lower() != "status":
                 continue
             if change["added"] in change_states:
                 changes.append(event["when"])
                 return event["when"] < appliance_build_datetime()
     else:
         return False
Example #2
0
 def can_test_on_upstream(self):
     change_states = {"POST", "MODIFIED"}
     # With these states, the change is in upstream
     if self.status not in {"POST", "MODIFIED", "ON_QA", "VERIFIED", "RELEASE_PENDING"}:
         return False
     history = self.get_history()["bugs"][0]["history"]
     changes = []
     # We look for status changes in the history
     for event in history:
         for change in event["changes"]:
             if change["field_name"].lower() != "status":
                 continue
             if change["added"] in change_states:
                 changes.append(event["when"])
                 return event["when"] < appliance_build_datetime()
     else:
         return False
Example #3
0
def pytest_runtest_setup(item):
    if not hasattr(item, "_bugzilla_bugs"):
        return

    skippers = set([])
    xfailers = set([])
    # We filter only bugs that are fixed in current release
    # Generic status-based skipping
    for bug in filter(lambda o: o is not None,
                      map(lambda bug: item._bugzilla_bugs.get_bug(bug.id), item._bugzilla_bugs)):
        if bug.status in {"NEW", "ASSIGNED", "ON_DEV"}:
            skippers.add(bug.id)

    # POST/MODIFIED for upstream
    states = {"POST", "MODIFIED"}
    for bug in filter(lambda b: b.status in states,
                      filter(lambda o: o is not None,
                             map(lambda bug: item._bugzilla_bugs.get_bug(bug.id),
                                 item._bugzilla_bugs))):
        history = bug.get_history()["bugs"][0]["history"]
        changes = []
        # We look for status changes in the history
        for event in history:
            for change in event["changes"]:
                if change["field_name"].lower() != "status":
                    continue
                if change["added"] in states:
                    changes.append(event["when"])
                    break
        if changes:
            if appliance_is_downstream():
                # The possible fix is definitely not in the downstream build
                skippers.add(bug.id)
                continue
            # Given that the current bug state is what we want, we select the last change to the bug
            last_change = changes[-1]
            if last_change < appliance_build_datetime():
                logger.info(
                    "Decided to test {} on upstream, because the appliance was built "
                    "after the bug {} status was modified".format(item.nodeid, bug.id)
                )
            else:
                skippers.add(bug.id)

    # Custom skip/xfail handler
    global_env = dict(
        bugs=item._bugzilla_bugs,
        appliance_version=current_version(),
        appliance_downstream=appliance_is_downstream(),
    )
    # We will now extend the env with fixtures, so they can be used in the guard functions
    # We will however add only those that are not in the global_env otherwise we could overwrite
    # our own stuff.
    for funcarg, value in item.callspec.params.iteritems():
        if funcarg not in global_env:
            global_env[funcarg] = value
    for bug in set(map(lambda bug: item._bugzilla_bugs.get_bug(bug.id), item._bugzilla_bugs)):
        local_env = {"bug": bug}
        local_env.update(global_env)
        if item._skip_func(**local_env):
            skippers.add(bug.id)
        if item._xfail_func(**local_env):
            xfailers.add(bug.id)

    # Separate loop for unskipping
    for bug in set(map(lambda id: item._bugzilla_bugs.get_bug(id), skippers)):
        if bug.id not in item._unskip_dict:
            continue
        local_env = {"bug": bug}
        local_env.update(global_env)
        if item._unskip_dict[bug.id](**local_env):
            skippers.discard(bug.id)

    # We now have to resolve what to do with this test item
    # xfailing takes precedence over skipping (xfail is via custom function)
    if xfailers:
        item.add_marker(
            pytest.mark.xfail(
                "Xfailing due to these bugs: {}".format(", ".join(map(str, xfailers)))))
    elif skippers:
        bz_url = urlparse(item._bugzilla.url)
        pytest.skip("Skipping due to these bugs:\n{}".format(
            "\n".join([
                "{}: {} ({}://{}/show_bug.cgi?id={})".format(
                    bug.status, bug.summary, bz_url.scheme, bz_url.netloc, bug.id)
                for bug
                in set(map(lambda id: item._bugzilla_bugs.get_bug(id), skippers))
            ])
        ))
    else:
        logger.info("No action required by Bugzilla for {}. All good!".format(item.nodeid))