Exemple #1
0
    def test_get_two(self):
        some_date = dateparse.parse_datetime('2018-10-06T00:22:58.074859+00:00')

        models.Signature.objects.create(
            signature='OOM | Small',
            first_build='20180920131237',
            first_date=some_date
        )
        models.Signature.objects.create(
            signature='OOM | Large',
            first_build='20180920131237',
            first_date=some_date
        )

        api = models.SignatureFirstDate()

        resp = api.get(signatures=['OOM | Small', 'OOM | Large'])
        assert resp['total'] == 2
        assert resp['hits'] == [
            {
                'first_build': '20180920131237',
                'first_date': '2018-10-06T00:22:58.074859+00:00',
                'signature': 'OOM | Small'
            },
            {
                'first_build': '20180920131237',
                'first_date': '2018-10-06T00:22:58.074859+00:00',
                'signature': 'OOM | Large'
            }
        ]
Exemple #2
0
    def test_get_two(self):
        some_date = dateparse.parse_datetime(
            "2018-10-06T00:22:58.074859+00:00")

        models.Signature.objects.create(signature="OOM | Small",
                                        first_build="20180920131237",
                                        first_date=some_date)
        models.Signature.objects.create(signature="OOM | Large",
                                        first_build="20180920131237",
                                        first_date=some_date)

        api = models.SignatureFirstDate()

        resp = api.get(signatures=["OOM | Small", "OOM | Large"])
        assert resp["total"] == 2
        assert resp["hits"] == [
            {
                "first_build": "20180920131237",
                "first_date": "2018-10-06T00:22:58.074859+00:00",
                "signature": "OOM | Small",
            },
            {
                "first_build": "20180920131237",
                "first_date": "2018-10-06T00:22:58.074859+00:00",
                "signature": "OOM | Large",
            },
        ]
Exemple #3
0
    def test_signature_first_date(self):
        api = models.SignatureFirstDate()

        def mocked_get(**options):
            return {'hits': [], 'total': 0}

        models.SignatureFirstDate.implementation().get.side_effect = mocked_get
        r = api.get(signatures=['Pickle::ReadBytes', 'FakeSignature'], )
        eq_(r['total'], 0)
Exemple #4
0
def topcrashers(request, days=None, possible_days=None, default_context=None):
    context = default_context or {}

    product = request.GET.get('product')
    versions = request.GET.getlist('version')
    crash_type = request.GET.get('process_type')
    os_name = request.GET.get('platform')
    result_count = request.GET.get('_facets_size')
    tcbs_mode = request.GET.get('_tcbs_mode')
    range_type = request.GET.get('_range_type')

    range_type = 'build' if range_type == 'build' else 'report'

    if not tcbs_mode or tcbs_mode not in ('realtime', 'byday'):
        tcbs_mode = 'realtime'

    if product not in context['active_versions']:
        raise http.Http404('Unrecognized product')

    context['product'] = product

    if not versions:
        # :(
        # simulate what the nav.js does which is to take the latest version
        # for this product.
        for pv in context['active_versions'][product]:
            if pv['is_featured']:
                url = '%s&version=%s' % (request.build_absolute_uri(),
                                         urlquote(pv['version']))
                return redirect(url)

    # See if all versions support builds. If not, refuse to show the "by build"
    # range option in the UI.
    versions_have_builds = True
    for version in versions:
        for pv in context['active_versions'][product]:
            if pv['version'] == version and not pv['has_builds']:
                versions_have_builds = False
                break

    context['versions_have_builds'] = versions_have_builds

    # Used to pick a version in the dropdown menu.
    context['version'] = versions[0]

    if tcbs_mode == 'realtime':
        end_date = timezone.now().replace(microsecond=0)
    elif tcbs_mode == 'byday':
        end_date = timezone.now().replace(hour=0,
                                          minute=0,
                                          second=0,
                                          microsecond=0)

    # settings.PROCESS_TYPES might contain tuple to indicate that some
    # are actual labels.
    process_types = []
    for option in settings.PROCESS_TYPES:
        if isinstance(option, (list, tuple)):
            process_types.append(option[0])
        else:
            process_types.append(option)
    if crash_type not in process_types:
        crash_type = 'browser'

    context['crash_type'] = crash_type

    os_api = models.Platforms()
    operating_systems = os_api.get()
    if os_name not in (os_['name'] for os_ in operating_systems):
        os_name = None

    context['os_name'] = os_name

    # set the result counts filter in the context to use in
    # the template. This way we avoid hardcoding it twice and
    # have it defined in one common location.
    context['result_counts'] = settings.TCBS_RESULT_COUNTS
    if result_count not in context['result_counts']:
        result_count = settings.TCBS_RESULT_COUNTS[0]

    context['result_count'] = result_count
    context['query'] = {
        'product': product,
        'versions': versions,
        'crash_type': crash_type,
        'os_name': os_name,
        'result_count': unicode(result_count),
        'mode': tcbs_mode,
        'range_type': range_type,
        'end_date': end_date,
        'start_date': end_date - datetime.timedelta(days=days),
    }

    api_results = get_topcrashers_results(
        product=product,
        version=versions,
        platform=os_name,
        process_type=crash_type,
        date=[
            '<' + end_date.isoformat(),
            '>=' + context['query']['start_date'].isoformat()
        ],
        _facets_size=result_count,
        _range_type=range_type,
    )

    if api_results['total'] > 0:
        tcbs = api_results['facets']['signature']
    else:
        tcbs = []

    count_of_included_crashes = 0
    signatures = []
    for crash in tcbs[:int(result_count)]:
        signatures.append(crash['signature'])
        count_of_included_crashes += crash['count']

    context['number_of_crashes'] = count_of_included_crashes
    context['total_percentage'] = api_results['total'] and (
        100.0 * count_of_included_crashes / api_results['total'])

    # Get augmented bugs data.
    bugs = defaultdict(list)
    if signatures:
        bugs_api = models.Bugs()
        for b in bugs_api.get(signatures=signatures)['hits']:
            bugs[b['signature']].append(b['id'])

    # Get augmented signature data.
    sig_date_data = {}
    if signatures:
        sig_api = models.SignatureFirstDate()
        # SignatureFirstDate().get_dates() is an optimized version
        # of SignatureFirstDate().get() that returns a dict of
        # signature --> dates.
        first_dates = sig_api.get_dates(signatures)
        for sig, dates in first_dates.items():
            sig_date_data[sig] = dates['first_date']

    for crash in tcbs:
        crash_counts = []
        # Due to the inconsistencies of OS usage and naming of
        # codes and props for operating systems the hacky bit below
        # is required. Socorro and the world will be a better place
        # once https://bugzilla.mozilla.org/show_bug.cgi?id=790642 lands.
        for operating_system in operating_systems:
            if operating_system['name'] == 'Unknown':
                # not applicable in this context
                continue
            os_code = operating_system['code'][0:3].lower()
            key = '%s_count' % os_code
            crash_counts.append([crash[key], operating_system['name']])

        crash['correlation_os'] = max(crash_counts)[1]
        sig = crash['signature']

        # Augment with bugs.
        if sig in bugs:
            if 'bugs' in crash:
                crash['bugs'].extend(bugs[sig])
            else:
                crash['bugs'] = bugs[sig]

        # Augment with first appearance dates.
        if sig in sig_date_data:
            crash['first_report'] = sig_date_data[sig]

        if 'bugs' in crash:
            crash['bugs'].sort(reverse=True)

    context['tcbs'] = tcbs
    context['days'] = days
    context['report'] = 'topcrasher'
    context['possible_days'] = possible_days
    context['total_crashing_signatures'] = len(signatures)
    context['total_number_of_crashes'] = api_results['total']
    context['process_type_values'] = []
    for option in settings.PROCESS_TYPES:
        if option == 'all':
            continue
        if isinstance(option, (list, tuple)):
            value, label = option
        else:
            value = option
            label = option.capitalize()
        context['process_type_values'].append((value, label))

    context['platform_values'] = settings.DISPLAY_OS_NAMES

    return render(request, 'topcrashers/topcrashers.html', context)
Exemple #5
0
    def test_signature_first_date_get_dates(self):
        api = models.SignatureFirstDate()

        now = timezone.now()
        tomorrow = now + datetime.timedelta(days=1)
        tomorrow_tomorrow = tomorrow + datetime.timedelta(days=1)

        def mocked_get(**kwargs):
            signatures = kwargs['signatures']
            # This mocking function really makes sure that only what is
            # expected to be called for is called for.
            # Basically, the first time it expects to be asked
            # about 'Sig 1' and 'Sig 2'.
            # The second time it expect to only be asked about 'Sig 3'.
            # Anything else will raise a NotImplementedError.
            if sorted(signatures) == ['Sig 1', 'Sig 2']:
                return {
                    'hits': [{
                        'signature': 'Sig 1',
                        'first_build': '201601010101',
                        'first_date': now,
                    }, {
                        'signature': 'Sig 2',
                        'first_build': '201602020202',
                        'first_date': tomorrow,
                    }],
                    'total':
                    2
                }
            elif sorted(signatures) == ['Sig 3']:
                return {
                    'hits': [{
                        'signature': 'Sig 3',
                        'first_build': '201603030303',
                        'first_date': tomorrow_tomorrow,
                    }],
                    'total':
                    1
                }
            raise NotImplementedError(signatures)

        models.SignatureFirstDate.implementation().get.side_effect = mocked_get
        r = api.get_dates(['Sig 1', 'Sig 2'])
        eq_(
            r, {
                'Sig 1': {
                    'first_build': '201601010101',
                    'first_date': now,
                },
                'Sig 2': {
                    'first_build': '201602020202',
                    'first_date': tomorrow,
                },
            })
        r = api.get_dates(['Sig 2', 'Sig 3'])
        eq_(
            r, {
                'Sig 2': {
                    'first_build': '201602020202',
                    'first_date': tomorrow,
                },
                'Sig 3': {
                    'first_build': '201603030303',
                    'first_date': tomorrow_tomorrow,
                },
            })
Exemple #6
0
def topcrashers(request, days=None, possible_days=None, default_context=None):
    context = default_context or {}

    product = request.GET.get('product')
    versions = request.GET.get('version')
    crash_type = request.GET.get('process_type')
    os_name = request.GET.get('platform')
    result_count = request.GET.get('_facets_size')
    tcbs_mode = request.GET.get('_tcbs_mode')

    if not tcbs_mode or tcbs_mode not in ('realtime', 'byday'):
        tcbs_mode = 'realtime'

    if product not in context['releases']:
        raise http.Http404('Unrecognized product')

    context['product'] = product

    if not versions:
        # :(
        # simulate what the nav.js does which is to take the latest version
        # for this product.
        for release in context['currentversions']:
            if release['product'] == product and release['featured']:
                url = '%s&version=%s' % (request.build_absolute_uri(),
                                         urlquote(release['version']))
                return redirect(url)
    else:
        versions = versions.split(';')

    context['version'] = versions[0]

    if tcbs_mode == 'realtime':
        end_date = datetime.datetime.utcnow().replace(microsecond=0)
    elif tcbs_mode == 'byday':
        end_date = datetime.datetime.utcnow().replace(hour=0,
                                                      minute=0,
                                                      second=0,
                                                      microsecond=0)

    if crash_type not in settings.PROCESS_TYPES:
        crash_type = 'browser'

    context['crash_type'] = crash_type

    os_api = models.Platforms()
    operating_systems = os_api.get()
    if os_name not in (os_['name'] for os_ in operating_systems):
        os_name = None

    context['os_name'] = os_name

    # set the result counts filter in the context to use in
    # the template. This way we avoid hardcoding it twice and
    # have it defined in one common location.
    context['result_counts'] = settings.TCBS_RESULT_COUNTS
    if result_count not in context['result_counts']:
        result_count = settings.TCBS_RESULT_COUNTS[0]

    context['result_count'] = result_count
    context['query'] = {
        'product': product,
        'versions': versions[0],
        'crash_type': crash_type,
        'os_name': os_name,
        'result_count': unicode(result_count),
        'mode': tcbs_mode,
        'end_date': end_date,
        'start_date': end_date - datetime.timedelta(days=days),
    }

    api_results = get_topcrashers_results(
        product=product,
        version=context['version'],
        platform=os_name,
        process_type=crash_type,
        date=[
            '<' + end_date.isoformat(),
            '>=' + context['query']['start_date'].isoformat()
        ],
        _facets_size=result_count,
    )

    if api_results['total'] > 0:
        tcbs = api_results['facets']['signature']
    else:
        tcbs = []

    count_of_included_crashes = 0
    signatures = []
    for crash in tcbs[:int(result_count)]:
        signatures.append(crash['signature'])
        count_of_included_crashes += crash['count']

    context['number_of_crashes'] = count_of_included_crashes
    context['total_percentage'] = api_results['total'] and (
        100.0 * count_of_included_crashes / api_results['total'])

    # Get augmented bugs data.
    bugs = defaultdict(list)
    if signatures:
        bugs_api = models.Bugs()
        for b in bugs_api.get(signatures=signatures)['hits']:
            bugs[b['signature']].append(b['id'])

    # Get augmented signature data.
    sig_date_data = {}
    if signatures:
        sig_api = models.SignatureFirstDate()
        first_dates = sig_api.get(signatures=signatures)
        for sig in first_dates['hits']:
            sig_date_data[sig['signature']] = sig['first_date']

    for crash in tcbs:
        crash_counts = []
        # Due to the inconsistencies of OS usage and naming of
        # codes and props for operating systems the hacky bit below
        # is required. Socorro and the world will be a better place
        # once https://bugzilla.mozilla.org/show_bug.cgi?id=790642 lands.
        for operating_system in operating_systems:
            if operating_system['name'] == 'Unknown':
                # not applicable in this context
                continue
            os_code = operating_system['code'][0:3].lower()
            key = '%s_count' % os_code
            crash_counts.append([crash[key], operating_system['name']])

        crash['correlation_os'] = max(crash_counts)[1]
        sig = crash['signature']

        # Augment with bugs.
        if sig in bugs:
            if 'bugs' in crash:
                crash['bugs'].extend(bugs[sig])
            else:
                crash['bugs'] = bugs[sig]

        # Augment with first appearance dates.
        if sig in sig_date_data:
            crash['first_report'] = isodate.parse_datetime(sig_date_data[sig])

        if 'bugs' in crash:
            crash['bugs'].sort(reverse=True)

    context['tcbs'] = tcbs
    context['days'] = days
    context['report'] = 'topcrasher'
    context['possible_days'] = possible_days
    context['total_crashing_signatures'] = len(signatures)
    context['total_number_of_crashes'] = api_results['total']
    context['process_type_values'] = (x for x in settings.PROCESS_TYPES
                                      if x != 'all')
    context['platform_values'] = settings.DISPLAY_OS_NAMES

    return render(request, 'topcrashers/topcrashers.html', context)