def for_sync()

in sync/notify/bugs.py [0:0]


def for_sync(sync: DownstreamSync,
             results: Results,
             ) -> Mapping[int, list[ResultsEntryStatus]]:
    """Create the bugs for followup work for test problems found in a sync.

    This creates bugs that will be owned by the triage owner of the component
    for any followup work that's revealed by the changes in a sync. Currently
    this is for crashes and certain kinds of failures e.g. Firefox-only failures
    that are not already known in the wpt metadata.

    :returns: A dict {bug_id: bug_info} where bug_info is a list of test results
              that are included in the bug, each represented as a tuple
              (test_id, subtest, results, status)"""
    rv: MutableMapping[int, list[ResultsEntryStatus]] = {}

    newrelic.agent.record_custom_event("sync_bug", params={
        "sync_bug": sync.bug,
    })

    new_crashes = list(results.iter_filter(lambda _test, _subtest, result:
                                           (result.has_crash("firefox") and
                                            not result.has_link(status="CRASH"))))

    new_failures = list(results.iter_filter(filter_test_failures))

    if not new_failures and not new_crashes:
        newrelic.agent.record_custom_event("sync_bug_nothing_relevant", params={
            "sync_bug": sync.bug,
        })
        return rv

    existing = sync.notify_bugs

    git_work = sync.gecko_worktree.get()
    path_prefix = env.config["gecko"]["path"]["wpt"]

    seen = set()

    for key, test_results, bug_data, link_status, require_opt_in in [
            ("crash", new_crashes, bug_data_crash, "CRASH", False),
            ("failure", new_failures, bug_data_failure, None, True)]:

        # Tests excluding those for which we already generated a bug
        test_results = [item for item in test_results
                        if (item[0], item[1]) not in seen]

        if not test_results:
            continue

        seen |= {(item[0], item[1]) for item in test_results}

        test_ids = list({test_id for test_id, _subtest, _result in test_results})
        test_id_by_path = test_ids_to_paths(git_work, test_ids)
        test_path_by_id = {}
        for path, ids in test_id_by_path.items():
            for test_id in ids:
                test_path_by_id[test_id] = os.path.relpath(path, path_prefix)

        paths = set(test_path_by_id.values())
        logger.info(f"Got paths {paths}")
        components = components_for_wpt_paths(git_work, paths)

        components_by_path = {}
        for component, component_paths in components.items():
            for path in component_paths:
                components_by_path[path] = component

        test_results_by_component = defaultdict(list)

        for test_id, subtest, test_result in test_results:
            test_path = test_path_by_id.get(test_id)
            if not test_path:
                # This can be missing if the test landed in a commit that's upstream but not here
                # so it's in wpt.fyi data but not here
                continue
            component = components_by_path[test_path]
            test_results_by_component[component].append((test_id, subtest, test_result))

        opt_in_components = {item.strip()
                             for item in
                             env.config["notify"].get("components", "").split(";")}

        for component, test_results in test_results_by_component.items():
            if component == "UNKNOWN":
                # For things with no component don't file a bug
                continue

            component_key = f"{key} :: {component}"

            if require_opt_in and component not in opt_in_components:
                logger.info("Not filing bugs for component %s" % component)
                newrelic.agent.record_custom_event("sync_bug_not_enabled", params={
                    "sync_bug": sync.bug,
                    "component": component
                })
                continue

            if component_key not in existing:
                product, component = component.split(" :: ")
                summary, comment = bug_data(sync,
                                            test_results,
                                            results.treeherder_url,
                                            results.wpt_sha)
                depends = []
                if sync.bug:
                    depends = [sync.bug]
                bug_id = make_bug(summary, comment, product, component, depends)
                sync.notify_bugs = sync.notify_bugs.copy(**{component_key: bug_id})  # type: ignore
                newrelic.agent.record_custom_event("sync_bug_filing", params={
                    "sync_bug": sync.bug,
                    "component": component
                })
            else:
                newrelic.agent.record_custom_event("sync_bug_existing", params={
                    "sync_bug": sync.bug,
                    "component": component
                })
                bug_id = existing[component_key]

            rv[bug_id] = [item + (link_status,) for item in test_results]

    return rv