def test_get_bugs_info(self):
        status_flags = Bugzilla.get_status_flags()
        bugs = ['701227', '701232']
        info = statusflags.get_bugs_info(bugs, status_flags)
        self.assertEqual(set(info.keys()), set(bugs))
        info1 = info[bugs[0]]
        self.assertEqual(info1['assigned'], True)
        self.assertEqual(info1['fixed'], True)
        self.assertEqual(info1['incomplete'], False)
        self.assertEqual(info1['no_change'], set())
        self.assertEqual(info1['patched'], True)
        self.assertEqual(info1['resolved'], False)
        self.assertEqual(info1['fixed_dates'][0],
                         utils.get_date_ymd('2011-11-11 10:26:06'))
        self.assertEqual(info1['last_change'],
                         utils.get_date_ymd('2013-01-14 16:31:50'))
        info2 = info[bugs[1]]
        self.assertEqual(info2['assigned'], True)
        self.assertEqual(info2['fixed'], True)
        self.assertEqual(info2['incomplete'], False)
        self.assertEqual(info2['no_change'], set())
        self.assertEqual(info2['patched'], False)
        self.assertEqual(info2['resolved'], True)
        self.assertEqual(info2['fixed_dates'][0],
                         utils.get_date_ymd('2011-11-10 03:13:31'))
        self.assertEqual(info2['last_change'],
                         utils.get_date_ymd('2015-03-12 15:17:16'))

        bugs = ['844479']
        fl = 'cf_status_firefox'
        info = statusflags.get_bugs_info(
            bugs, {
                'nightly': fl + '23',
                'aurora': fl + '22',
                'beta': fl + '21',
                'release': fl + '20'
            })
        self.assertEqual(set(info.keys()), set(bugs))
        info3 = info[bugs[0]]
        self.assertEqual(info3['assigned'], True)
        self.assertEqual(info3['fixed'], True)
        self.assertEqual(info3['incomplete'], False)
        self.assertEqual(info3['no_change'], {'aurora', 'beta'})
        self.assertEqual(info3['patched'], True)
        self.assertEqual(info3['resolved'], True)
        self.assertEqual(info3['fixed_dates'][0],
                         utils.get_date_ymd('2013-08-06 21:12:03'))
        self.assertEqual(info3['last_change'],
                         utils.get_date_ymd('2013-08-20 19:26:07'))
    def test_get_partial(self):
        channel = ['release', 'beta', 'aurora', 'nightly', 'esr']
        signature = 'js::GCMarker::processMarkStackTop'
        bugids = socorro.Bugs.get_bugs([signature])
        base_versions = {
            'nightly': 51,
            'aurora': 50,
            'beta': 49,
            'release': 48,
            'esr': 45
        }

        self.assertEqual(
            set(bugids[signature]), {
                792226, 789892, 719114, 730283, 1257309, 941491, 745334,
                772441, 952381
            })

        start_date, min_date, versions_by_channel, start_date_by_channel, base_versions = statusflags.get_versions_info(
            'Firefox', base_versions=base_versions)
        search_date = statusflags.get_search_date('', start_date, '2016-09-14')
        sgninfo = statusflags.get_signatures(100, 'Firefox',
                                             versions_by_channel, channel,
                                             search_date, [signature], [],
                                             False)
        status_flags = Bugzilla.get_status_flags(base_versions=base_versions)
        bugs_history_info = statusflags.get_bugs_info(bugids[signature],
                                                      status_flags)
        last_bugs_info, _ = statusflags.get_last_bugs_info(
            bugids[signature], signature, sgninfo, [], bugs_history_info,
            min_date)

        self.assertEqual(last_bugs_info['resolved-fixed-patched'],
                         ['', utils.get_guttenberg_death()])
        self.assertEqual(last_bugs_info['resolved-fixed-unpatched'],
                         ['', utils.get_guttenberg_death()])
        self.assertEqual(
            last_bugs_info['resolved-unfixed'],
            ['952381', utils.get_date_ymd('2014-05-13 12:12:41')])
        self.assertEqual(last_bugs_info['unresolved-assigned'],
                         ['', utils.get_guttenberg_death()])
        self.assertEqual(
            last_bugs_info['unresolved-unassigned'],
            ['719114', utils.get_date_ymd('2016-08-30 23:15:17')])

        last_bug = statusflags.get_last_bug(bugids[signature], signature,
                                            sgninfo, [], bugs_history_info,
                                            min_date)
        self.assertEqual(last_bug, '719114')
    def test_get_bugs_info(self):
        status_flags = Bugzilla.get_status_flags()
        bugs = ['701227', '701232']
        info = statusflags.get_bugs_info(bugs, status_flags)
        self.assertEqual(set(info.keys()), set(bugs))
        info1 = info[bugs[0]]
        self.assertEqual(info1['assigned'], True)
        self.assertEqual(info1['fixed'], True)
        self.assertEqual(info1['incomplete'], False)
        self.assertEqual(info1['no_change'], set())
        self.assertEqual(info1['patched'], True)
        self.assertEqual(info1['resolved'], False)
        self.assertEqual(info1['fixed_dates'][0], utils.get_date_ymd('2011-11-11 10:26:06'))
        self.assertEqual(info1['last_change'], utils.get_date_ymd('2013-01-14 16:31:50'))
        info2 = info[bugs[1]]
        self.assertEqual(info2['assigned'], True)
        self.assertEqual(info2['fixed'], True)
        self.assertEqual(info2['incomplete'], False)
        self.assertEqual(info2['no_change'], set())
        self.assertEqual(info2['patched'], False)
        self.assertEqual(info2['resolved'], True)
        self.assertEqual(info2['fixed_dates'][0], utils.get_date_ymd('2011-11-10 03:13:31'))
        self.assertEqual(info2['last_change'], utils.get_date_ymd('2015-03-12 15:17:16'))

        bugs = ['844479']
        fl = 'cf_status_firefox'
        info = statusflags.get_bugs_info(bugs, {'nightly': fl + '23',
                                                'aurora': fl + '22',
                                                'beta': fl + '21',
                                                'release': fl + '20'})
        self.assertEqual(set(info.keys()), set(bugs))
        info3 = info[bugs[0]]
        self.assertEqual(info3['assigned'], True)
        self.assertEqual(info3['fixed'], True)
        self.assertEqual(info3['incomplete'], False)
        self.assertEqual(info3['no_change'], {'aurora', 'beta'})
        self.assertEqual(info3['patched'], True)
        self.assertEqual(info3['resolved'], True)
        self.assertEqual(info3['fixed_dates'][0], utils.get_date_ymd('2013-08-06 21:12:03'))
        self.assertEqual(info3['last_change'], utils.get_date_ymd('2013-08-20 19:26:07'))
    def test_get_partial(self):
        channel = ['release', 'beta', 'aurora', 'nightly', 'esr']
        signature = 'js::GCMarker::processMarkStackTop'
        bugids = socorro.Bugs.get_bugs([signature])
        base_versions = {'nightly': 51, 'aurora': 50, 'beta': 49, 'release': 48, 'esr': 45}

        self.assertEqual(set(bugids[signature]), {792226, 789892, 719114, 730283, 1257309, 941491, 745334, 772441, 952381})

        start_date, min_date, versions_by_channel, start_date_by_channel, base_versions = statusflags.get_versions_info('Firefox', base_versions=base_versions)
        search_date = statusflags.get_search_date('', start_date, '2016-09-14')
        sgninfo = statusflags.get_signatures(100, 'Firefox', versions_by_channel, channel, search_date, [signature], [], False)
        status_flags = Bugzilla.get_status_flags(base_versions=base_versions)
        bugs_history_info = statusflags.get_bugs_info(bugids[signature], status_flags)
        last_bugs_info, _ = statusflags.get_last_bugs_info(bugids[signature], signature, sgninfo, [], bugs_history_info, min_date)

        self.assertEqual(last_bugs_info['resolved-fixed-patched'], ['', utils.get_guttenberg_death()])
        self.assertEqual(last_bugs_info['resolved-fixed-unpatched'], ['', utils.get_guttenberg_death()])
        self.assertEqual(last_bugs_info['resolved-unfixed'], ['952381', utils.get_date_ymd('2014-05-13 12:12:41')])
        self.assertEqual(last_bugs_info['unresolved-assigned'], ['', utils.get_guttenberg_death()])
        self.assertEqual(last_bugs_info['unresolved-unassigned'], ['719114', utils.get_date_ymd('2016-08-30 23:15:17')])

        last_bug = statusflags.get_last_bug(bugids[signature], signature, sgninfo, [], bugs_history_info, min_date)
        self.assertEqual(last_bug, '719114')
Exemple #5
0
def get(product='Firefox', limit=1000, verbose=False, search_start_date='', end_date=None, signatures=[], bug_ids=[], max_bugs=-1, base_versions=None, check_for_fx=True, check_bz_version=True, check_noisy=True):
    """Get crashes info

    Args:
        product (Optional[str]): the product
        limit (Optional[int]): the number of crashes to get from tcbs

    Returns:
        dict: contains all the info about how to update flags
    """
    p = product.lower()
    if p == 'firefox':
        product = 'Firefox'
    elif p == 'fennecandroid':
        product = 'FennecAndroid'

    channel = ['release', 'beta', 'aurora', 'nightly']
    if product == 'Firefox':
        channel.append('esr')

    start_date, min_date, versions_by_channel, start_date_by_channel, base_versions = get_versions_info(product, date=end_date, base_versions=base_versions)
    nv = Bugzilla.get_nightly_version()

    if check_bz_version and nv != base_versions['nightly']:
        __warn('Mismatch between nightly version from Bugzilla (%d) and Socorro (%d)' % (nv, base_versions['nightly']), verbose)
        return None

    if check_bz_version and (base_versions['aurora'] != nv - 1 or base_versions['beta'] != nv - 2 or base_versions['release'] != nv - 3):
        __warn('All versions are not up to date (Bugzilla nightly version is %d): %s' % (nv, base_versions), verbose)
        return None

    __warn('Versions: %s' % versions_by_channel, verbose)
    __warn('Start dates: %s' % start_date_by_channel, verbose)

    if not end_date:
        end_date = utils.get_date('today')

    search_date = get_search_date(search_start_date, start_date, end_date)

    signatures = get_signatures(limit, product, versions_by_channel, channel, search_date, signatures, bug_ids, verbose)
    # signatures == { 'foo::bar': {'affected_channels': [('release', 1234), ...],
    #                              'bugs': None,
    #                              'platforms': ['Windows'],
    #                              'selected_bug': None}, ... }

    __warn('Collected signatures: %d' % len(signatures), verbose)

    # get the bugs for each signatures
    bugs_by_signature = socorro.Bugs.get_bugs(list(signatures.keys()))

    # if we've some bugs in bug_ids then we must remove the other ones for a given signature
    if bug_ids:
        bids = set(bug_ids)
        for s, bugids in bugs_by_signature.items():
            inter = bids.intersection(bugids)
            if inter:
                bugs_by_signature[s] = inter

    __warn('Collected bugs in Socorro: Ok', verbose)

    bugs, bugs_count = reduce_set_of_bugs(bugs_by_signature)

    __warn('Remove duplicates: Ok', verbose)
    __warn('Bugs to analyze: %d' % bugs_count, verbose)

    # we filter the bugs to remove meaningless ones
    if not bug_ids:
        bugs = filter_bugs(bugs, product)

    status_flags = Bugzilla.get_status_flags(base_versions=base_versions)

    # we get the "better" bug where to update the info
    bugs_history_info = get_bugs_info(bugs, status_flags)

    patched_bugs = []
    for bugid, hinfo in bugs_history_info.items():
        if hinfo['patched']:
            patched_bugs.append(bugid)

    if patched_bugs:
        patch_info = dataanalysis.analyze_bugs(patched_bugs, min_date=min_date, base_versions=base_versions)
    else:
        patch_info = {}

    crashes_to_reopen = []
    bugs.clear()
    for s, v in bugs_by_signature.items():
        info = signatures[s]
        no_change = set()
        if v:
            bug_to_touch = get_last_bug(v, s, signatures[s], patch_info, bugs_history_info, min_date)
            if bug_to_touch:
                no_change = bugs_history_info[bug_to_touch]['no_change']
            else:
                crashes_to_reopen.append(s)
        else:
            bug_to_touch = None
        info['selected_bug'] = bug_to_touch
        info['bugs'] = v
        info['no_change'] = no_change
        if bug_to_touch:
            bugs.add(bug_to_touch)

    __warn('Collected last bugs: %d' % len(bugs), verbose)

    # add bug info in signatures
    add_bug_info(signatures, list(bugs), status_flags, product, verbose)

    # analyze the signatures
    analysis = analyze(signatures, status_flags, base_versions)

    if max_bugs > 0:
        __analysis = {}
        count = 0
        for signature, info in analysis.items():
            if not check_for_fx or info['firefox']:
                __analysis[signature] = info
                count += 1
                if count == max_bugs:
                    analysis = __analysis
                    break

    __warn('Analysis: Ok', verbose)

    positions_result, positions = get_crash_positions(-1, product, versions_by_channel, channel, search_date=search_date, verbose=verbose)

    # Now get the number of crashes for each signature
    trends = get_stats_for_past_weeks(product, channel, start_date_by_channel, versions_by_channel, analysis, search_start_date, end_date, check_for_fx=check_for_fx)

    if check_noisy:
        noisy = get_noisy(trends, analysis)
        __warn('Noisy signatures: %s' % [analysis[s] for s in noisy], verbose)
    else:
        noisy = set()

    __warn('Collected trends: Ok\n', verbose)

    positions_result.wait()

    # replace dictionary containing trends by a list
    empty_ranks = {'browser': -1, 'content': -1, 'plugin': -1, 'gpu': -1}
    for signature, i in trends.items():
        if signature in noisy:
            del analysis[signature]
        else:
            signature_info = analysis[signature]
            ranks = signature_info['rank']
            for chan, trend in i.items():
                i[chan] = [trend[week] for week in sorted(trend.keys(), reverse=False)]
                ranks[chan] = positions[chan].get(signature, empty_ranks)
            signature_info['trend'] = i

    __prettywarn(analysis, verbose)

    return {'status_flags': status_flags,
            'base_versions': base_versions,
            'start_dates': start_date_by_channel,
            'signatures': analysis,
            'end_date': end_date}
def get(product='Firefox',
        limit=1000,
        verbose=False,
        search_start_date='',
        end_date=None,
        signatures=[],
        bug_ids=[],
        max_bugs=-1,
        base_versions=None,
        check_for_fx=True,
        check_bz_version=True,
        check_noisy=True):
    """Get crashes info

    Args:
        product (Optional[str]): the product
        limit (Optional[int]): the number of crashes to get from tcbs

    Returns:
        dict: contains all the info about how to update flags
    """
    p = product.lower()
    if p == 'firefox':
        product = 'Firefox'
    elif p == 'fennecandroid':
        product = 'FennecAndroid'

    channel = ['release', 'beta', 'aurora', 'nightly']
    if product == 'Firefox':
        channel.append('esr')

    start_date, min_date, versions_by_channel, start_date_by_channel, base_versions = get_versions_info(
        product, date=end_date, base_versions=base_versions)
    nv = Bugzilla.get_nightly_version()

    if check_bz_version and nv != base_versions['nightly']:
        __warn(
            'Mismatch between nightly version from Bugzilla (%d) and Socorro (%d)'
            % (nv, base_versions['nightly']), verbose)
        return None

    if check_bz_version and (base_versions['aurora'] != nv - 1
                             or base_versions['beta'] != nv - 2
                             or base_versions['release'] != nv - 3):
        __warn(
            'All versions are not up to date (Bugzilla nightly version is %d): %s'
            % (nv, base_versions), verbose)
        return None

    __warn('Versions: %s' % versions_by_channel, verbose)
    __warn('Start dates: %s' % start_date_by_channel, verbose)

    if not end_date:
        end_date = utils.get_date('today')

    search_date = get_search_date(search_start_date, start_date, end_date)

    signatures = get_signatures(limit, product, versions_by_channel, channel,
                                search_date, signatures, bug_ids, verbose)
    # signatures == { 'foo::bar': {'affected_channels': [('release', 1234), ...],
    #                              'bugs': None,
    #                              'platforms': ['Windows'],
    #                              'selected_bug': None}, ... }

    __warn('Collected signatures: %d' % len(signatures), verbose)

    # get the bugs for each signatures
    bugs_by_signature = socorro.Bugs.get_bugs(list(signatures.keys()))

    # if we've some bugs in bug_ids then we must remove the other ones for a given signature
    if bug_ids:
        bids = set(bug_ids)
        for s, bugids in bugs_by_signature.items():
            inter = bids.intersection(bugids)
            if inter:
                bugs_by_signature[s] = inter

    __warn('Collected bugs in Socorro: Ok', verbose)

    bugs, bugs_count = reduce_set_of_bugs(bugs_by_signature)

    __warn('Remove duplicates: Ok', verbose)
    __warn('Bugs to analyze: %d' % bugs_count, verbose)

    # we filter the bugs to remove meaningless ones
    if not bug_ids:
        bugs = filter_bugs(bugs, product)

    status_flags = Bugzilla.get_status_flags(base_versions=base_versions)

    # we get the "better" bug where to update the info
    bugs_history_info = get_bugs_info(bugs, status_flags)

    patched_bugs = []
    for bugid, hinfo in bugs_history_info.items():
        if hinfo['patched']:
            patched_bugs.append(bugid)

    if patched_bugs:
        patch_info = dataanalysis.analyze_bugs(patched_bugs,
                                               min_date=min_date,
                                               base_versions=base_versions)
    else:
        patch_info = {}

    crashes_to_reopen = []
    bugs.clear()
    for s, v in bugs_by_signature.items():
        info = signatures[s]
        no_change = set()
        if v:
            bug_to_touch = get_last_bug(v, s, signatures[s], patch_info,
                                        bugs_history_info, min_date)
            if bug_to_touch:
                no_change = bugs_history_info[bug_to_touch]['no_change']
            else:
                crashes_to_reopen.append(s)
        else:
            bug_to_touch = None
        info['selected_bug'] = bug_to_touch
        info['bugs'] = v
        info['no_change'] = no_change
        if bug_to_touch:
            bugs.add(bug_to_touch)

    __warn('Collected last bugs: %d' % len(bugs), verbose)

    # add bug info in signatures
    add_bug_info(signatures, list(bugs), status_flags, product, verbose)

    # analyze the signatures
    analysis = analyze(signatures, status_flags, base_versions)

    if max_bugs > 0:
        __analysis = {}
        count = 0
        for signature, info in analysis.items():
            if not check_for_fx or info['firefox']:
                __analysis[signature] = info
                count += 1
                if count == max_bugs:
                    analysis = __analysis
                    break

    __warn('Analysis: Ok', verbose)

    positions_result, positions = get_crash_positions(-1,
                                                      product,
                                                      versions_by_channel,
                                                      channel,
                                                      search_date=search_date,
                                                      verbose=verbose)

    # Now get the number of crashes for each signature
    trends = get_stats_for_past_weeks(product,
                                      channel,
                                      start_date_by_channel,
                                      versions_by_channel,
                                      analysis,
                                      search_start_date,
                                      end_date,
                                      check_for_fx=check_for_fx)

    if check_noisy:
        noisy = get_noisy(trends, analysis)
        __warn('Noisy signatures: %s' % [analysis[s] for s in noisy], verbose)
    else:
        noisy = set()

    __warn('Collected trends: Ok\n', verbose)

    positions_result.wait()

    # replace dictionary containing trends by a list
    empty_ranks = {'browser': -1, 'content': -1, 'plugin': -1, 'gpu': -1}
    for signature, i in trends.items():
        if signature in noisy:
            del analysis[signature]
        else:
            signature_info = analysis[signature]
            ranks = signature_info['rank']
            for chan, trend in i.items():
                i[chan] = [
                    trend[week] for week in sorted(trend.keys(), reverse=False)
                ]
                ranks[chan] = positions[chan].get(signature, empty_ranks)
            signature_info['trend'] = i

    __prettywarn(analysis, verbose)

    return {
        'status_flags': status_flags,
        'base_versions': base_versions,
        'start_dates': start_date_by_channel,
        'signatures': analysis,
        'end_date': end_date
    }