Exemplo n.º 1
0
def get(bug_ids: Iterable[int]) -> Dict[int, dict]:
    """Function to retrieve Bug Information including history, comments using Bugzilla REST API and attachment using Bugzilla package.

    :param bug_ids: find bug information for these `bug_ids`
    :type bug_ids: list of integers or str or int
    :return: dict with key as `id`(int) of a bug,  and values as bug_information
    :rtype: dict
    """

    def attachmenthandler(bug, bug_id):
        bug_id = int(bug_id)

        if bug_id not in new_bugs:
            new_bugs[bug_id] = dict()

        new_bugs[bug_id]["attachments"] = bug

    bug_ids = sorted(set(bug_ids))

    new_bugs = dict()

    batch_size = Bugzilla.BUGZILLA_CHUNK_SIZE

    # Getting _default, history and comments information using REST API
    # Attachment meta data is retrieved using Bugzilla module

    for i in range(0, len(bug_ids), batch_size):
        batch = bug_ids[i : i + batch_size]
        batch_of_ids = ",".join(map(str, batch))

        # "include_fields": "_default,history,comments,attachments",
        # Attachments data size is heavy, so handling them separately

        params_for_custom_fields = {
            "id": batch_of_ids,
            "include_fields": "_default,history,comments",
        }
        response = utils.get_session("bugzilla").get(
            "https://bugzilla.mozilla.org/rest/bug", params=params_for_custom_fields
        )
        response.raise_for_status()

        batch_of_bugs_info = response.json()
        batch_of_bugs_info = {
            int(a_bug["id"]): a_bug for a_bug in batch_of_bugs_info["bugs"]
        }

        new_bugs.update(batch_of_bugs_info)

        Bugzilla(
            batch,
            bughandler=None,
            commenthandler=None,
            comment_include_fields=None,
            attachmenthandler=attachmenthandler,
            attachment_include_fields=ATTACHMENT_INCLUDE_FIELDS,
            historyhandler=None,
        ).get_data().wait()

    return new_bugs
Exemplo n.º 2
0
def get_product_component_count():
    """Returns a dictionary where keys are full components (in the form of
    `{product}::{component}`) and the value of the number of bugs for the
    given full components. Full component with 0 bugs are returned.
    """
    url, params = get_product_component_csv_report()
    csv_file = utils.get_session("bugzilla").get(url, params=params)
    csv_file.raise_for_status()
    content = csv_file.text

    csv_content = content.splitlines()
    component_key = "Component / Product"

    bugs_number = {}

    csv_reader = csv.DictReader(csv_content)
    for row in csv_reader:
        # Extract the component key
        component = row[component_key]

        for product, raw_value in row.items():
            if product == component_key:
                continue

            value = int(raw_value)

            full_comp = f"{product}::{component}"
            bugs_number[full_comp] = value

    return bugs_number
Exemplo n.º 3
0
 def fetch_events(self, events_url: str) -> list:
     self.api_limit()
     logger.info(f"Fetching {events_url}")
     headers = {"Authorization": "token {}".format(self.get_token())}
     response = get_session("github").get(events_url, headers=headers)
     response.raise_for_status()
     events_raw = response.json()
     return events_raw
Exemplo n.º 4
0
def count_bugs(bug_query_params):
    bug_query_params["count_only"] = 1

    r = utils.get_session("bugzilla").get(
        "https://bugzilla.mozilla.org/rest/bug", params=bug_query_params)
    r.raise_for_status()
    count = r.json()["bug_count"]

    return count
Exemplo n.º 5
0
def get_component_team_mapping() -> dict:
    r = utils.get_session("bugzilla").get(
        "https://bugzilla.mozilla.org/rest/config/component_teams",
        headers={
            "X-Bugzilla-API-Key": Bugzilla.TOKEN,
            "User-Agent": "bugbug"
        },
    )
    r.raise_for_status()
    return r.json()
Exemplo n.º 6
0
    def function(self, filename, code):
        url = f"{self.base_url}/function?file_name={filename}"
        r = utils.get_session("code_analysis").post(url,
                                                    data=code,
                                                    headers=HEADERS)

        if not r.ok:
            return {}

        return r.json()
Exemplo n.º 7
0
def get_component_team_mapping() -> Dict[str, Dict[str, str]]:
    r = utils.get_session("bugzilla").get(
        "https://bugzilla.mozilla.org/rest/product?type=accessible&include_fields=name&include_fields=components.name&include_fields=components.team_name",
        headers={"X-Bugzilla-API-Key": Bugzilla.TOKEN, "User-Agent": "bugbug"},
    )
    r.raise_for_status()

    mapping: Dict[str, Dict[str, str]] = collections.defaultdict(dict)
    for product in r.json()["products"]:
        for component in product["components"]:
            mapping[product["name"]][component["name"]] = component["team_name"]

    return mapping
Exemplo n.º 8
0
def get_github_issues_update_time(owner: str, repo: str,
                                  issue_nums: Sequence[int]) -> dict:
    header = {"Authorization": "token {}".format(GITHUB_TOKEN)}
    repo_url = f"https://api.github.com/repos/{owner}/{repo}/issues/"

    issues = {}
    for issue_num in issue_nums:
        issue_url = repo_url + str(issue_num)
        response = utils.get_session("github").get(issue_url, headers=header)
        response.raise_for_status()
        raw_issue = response.json()
        issues[raw_issue["number"]] = raw_issue["updated_at"]

    return issues
Exemplo n.º 9
0
    def metrics(self, filename, code, unit=True):
        """
        When unit is True, then only metrics for top-level is returned,
        when False, then we get detailed metrics for all classes, functions, nested functions, ...
        """
        unit = 1 if unit else 0
        url = f"{self.base_url}/metrics?file_name={filename}&unit={unit}"
        r = utils.get_session("code_analysis").post(url,
                                                    data=code,
                                                    headers=HEADERS)

        if not r.ok:
            return {}

        return r.json()
Exemplo n.º 10
0
def get_groups_users(group_names: List[str]) -> List[str]:
    r = utils.get_session("bugzilla").get(
        "https://bugzilla.mozilla.org/rest/group",
        params={
            "names": group_names,
            "membership": "1",
        },
        headers={"X-Bugzilla-API-Key": Bugzilla.TOKEN, "User-Agent": "bugbug"},
    )
    r.raise_for_status()

    return [
        member["email"]
        for group in r.json()["groups"]
        for member in group["membership"]
    ]
Exemplo n.º 11
0
def get_product_component_count(months: int = 12) -> Dict[str, int]:
    """Returns a dictionary where keys are full components (in the form of
    `{product}::{component}`) and the value of the number of bugs for the
    given full components. Full component with 0 bugs are returned.
    """
    since = datetime.utcnow() - relativedelta(months=months)

    # Base params
    params = {
        "f1": "creation_ts",
        "o1": "greaterthan",
        "v1": since.strftime("%Y-%m-%d"),
        "x_axis_field": "product",
        "y_axis_field": "component",
        "action": "wrap",
        "ctype": "csv",
        "format": "table",
    }

    csv_file = utils.get_session("bugzilla").get(
        PRODUCT_COMPONENT_CSV_REPORT_URL, params=params
    )
    csv_file.raise_for_status()
    content = csv_file.text

    csv_content = content.splitlines()
    component_key = "Component / Product"

    bugs_number = {}

    csv_reader = csv.DictReader(csv_content)
    for row in csv_reader:
        # Extract the component key
        component = row[component_key]

        for product, raw_value in row.items():
            if product == component_key:
                continue

            value = int(raw_value)

            full_comp = f"{product}::{component}"
            bugs_number[full_comp] = value

    return bugs_number
Exemplo n.º 12
0
def get_bugs_last_change_time(bug_ids):
    query = {
        "id": ",".join(map(str, bug_ids)),
        "include_fields": ["last_change_time", "id"],
    }
    header = {"X-Bugzilla-API-Key": "", "User-Agent": "bugbug"}
    response = utils.get_session("bugzilla").get(
        BUGZILLA_API_URL, params=query, headers=header, verify=True, timeout=30
    )
    response.raise_for_status()

    raw_bugs = response.json()

    bugs = {}

    for bug in raw_bugs["bugs"]:
        bugs[bug["id"]] = bug["last_change_time"]

    return bugs
Exemplo n.º 13
0
def get_bugs_last_change_time(bug_ids):
    query = {
        "include_fields": ["last_change_time", "id"],
    }
    header = {"X-Bugzilla-API-Key": BUGZILLA_TOKEN, "User-Agent": "bugbug"}

    bugs = {}
    for i in range(0, len(bug_ids), Bugzilla.BUGZILLA_CHUNK_SIZE):
        query["id"] = bug_ids[i : (i + Bugzilla.BUGZILLA_CHUNK_SIZE)]
        response = utils.get_session("bugzilla").get(
            BUGZILLA_API_URL, params=query, headers=header, verify=True, timeout=30
        )
        response.raise_for_status()

        raw_bugs = response.json()

        for bug in raw_bugs["bugs"]:
            bugs[bug["id"]] = bug["last_change_time"]

    return bugs
Exemplo n.º 14
0
    def fetch_issues(self,
                     url: str,
                     retrieve_events: bool,
                     params: dict = None) -> tuple[list[IssueDict], dict]:
        self.api_limit()
        headers = {"Authorization": "token {}".format(self.get_token())}
        response = get_session("github").get(url,
                                             params=params,
                                             headers=headers)
        response.raise_for_status()
        data = response.json()

        # If only one issue is requested, add it to a list
        if isinstance(data, dict):
            data = [data]

        logger.info(f"Fetching {url}")

        if retrieve_events:
            for item in data:
                events = self.fetch_events(item["events_url"])
                item.update({"events": events})

        return data, response.links
Exemplo n.º 15
0
def calculate_maintenance_effectiveness_indicator(
    team,
    from_date,
    to_date,
    components=None,
):
    data: dict[str, dict[str, int]] = {
        "opened": {},
        "closed": {},
    }

    for severity in MAINTENANCE_EFFECTIVENESS_SEVERITY_WEIGHTS.keys():
        params = {
            "count_only": 1,
            "type": "defect",
            "team_name": team,
            "chfieldfrom": from_date.strftime("%Y-%m-%d"),
            "chfieldto": to_date.strftime("%Y-%m-%d"),
        }

        if severity != "--":
            params["bug_severity"] = severity

        if components is not None:
            params["component"] = components

        for query_type in ("opened", "closed"):
            if query_type == "opened":
                params["chfield"] = "[Bug creation]"
            elif query_type == "closed":
                params.update(
                    {
                        "chfield": "cf_last_resolved",
                        "f1": "resolution",
                        "o1": "notequals",
                        "v1": "---",
                    }
                )

            r = utils.get_session("bugzilla").get(
                "https://bugzilla.mozilla.org/rest/bug",
                params=params,
                headers={"User-Agent": "bugbug"},
            )
            r.raise_for_status()

            data[query_type][severity] = r.json()["bug_count"]

    print("Before applying weights:")
    print(data)

    for query_type in ("opened", "closed"):
        data[query_type]["--"] = data[query_type]["--"] - sum(
            data[query_type][s]
            for s in MAINTENANCE_EFFECTIVENESS_SEVERITY_WEIGHTS.keys()
            if s != "--"
        )

        # Apply weights.
        for (
            severity,
            weight,
        ) in MAINTENANCE_EFFECTIVENESS_SEVERITY_WEIGHTS.items():
            data[query_type][severity] *= weight

    print("After applying weights:")
    print(data)

    return (1 + sum(data["closed"].values())) / (1 + sum(data["opened"].values()))