def check_appver_filters(self, appver='', expected=''): if not expected: expected = appver r = self.client.get(self.url, dict(appver=appver)) eq_(r.status_code, 200) vs = list( ApplicationsVersions.objects.values_list('max__version', flat=True).distinct()) try: if expected not in vs and float(floor_version(expected)): vs.append(expected) except ValueError: pass vs = [float(floor_version(v)) for v in vs] ul = pq(r.content)('#search-facets ul.facet-group').eq(1) app = unicode(r.context['request'].APP.pretty) eq_(r.context['query']['appver'], expected) all_ = r.context['versions'].pop(0) eq_(all_.text, 'Any %s' % app) eq_(all_.selected, not expected) eq_(json.loads(ul.find('a:first').attr('data-params')), dict(appver='', page=None)) for label, av in zip(r.context['versions'], sorted(vs, reverse=True)): av = str(av) eq_(label.text, '%s %s' % (app, av)) eq_(label.selected, expected == av) a = ul.find('a').filter(lambda x: pq(this).text() == label.text) eq_(json.loads(a.attr('data-params')), dict(appver=av, page=None))
def check_appver_filters(self, appver="", expected=""): if not expected: expected = appver r = self.client.get(self.url, dict(appver=appver)) eq_(r.status_code, 200) vs = list(ApplicationsVersions.objects.values_list("max__version", flat=True).distinct()) try: if expected not in vs and float(floor_version(expected)): vs.append(expected) except ValueError: pass vs = [float(floor_version(v)) for v in vs] ul = pq(r.content)("#search-facets ul.facet-group").eq(1) app = unicode(r.context["request"].APP.pretty) eq_(r.context["query"]["appver"], expected) all_ = r.context["versions"].pop(0) eq_(all_.text, "Any %s" % app) eq_(all_.selected, not expected) eq_(json.loads(ul.find("a:first").attr("data-params")), dict(appver="", page=None)) for label, av in zip(r.context["versions"], sorted(vs, reverse=True)): av = str(av) eq_(label.text, "%s %s" % (app, av)) eq_(label.selected, expected == av) a = ul.find("a").filter(lambda x: pq(this).text() == label.text) eq_(json.loads(a.attr("data-params")), dict(appver=av, page=None))
def check_appver_filters(self, appver='', expected=''): if not expected: expected = appver r = self.client.get(self.url, dict(appver=appver)) eq_(r.status_code, 200) vs = list(ApplicationsVersions.objects.values_list( 'max__version', flat=True).distinct()) try: if expected not in vs and float(floor_version(expected)): vs.append(expected) except ValueError: pass vs = [float(floor_version(v)) for v in vs] ul = pq(r.content)('#search-facets ul.facet-group').eq(1) app = unicode(r.context['request'].APP.pretty) eq_(r.context['query']['appver'], expected) all_ = r.context['versions'].pop(0) eq_(all_.text, 'Any %s' % app) eq_(all_.selected, not expected) eq_(json.loads(ul.find('a:first').attr('data-params')), dict(appver='', page=None)) for label, av in zip(r.context['versions'], sorted(vs, reverse=True)): av = str(av) eq_(label.text, '%s %s' % (app, av)) eq_(label.selected, expected == av) a = ul.find('a').filter(lambda x: pq(this).text() == label.text) eq_(json.loads(a.attr('data-params')), dict(appver=av, page=None))
def test_appver_long(self): too_big = vnum(vint(MAXVERSION + 1)) just_right = vnum(vint(MAXVERSION)) assert self.check_appver_filters(too_big, floor_version(just_right)), "All I ask is do not crash" eq_( self.check_appver_filters("9999999", "9999999.0"), [ {"text": u"Firefox 9999999.0", "selected": True, "urlparams": {"appver": "9999999.0"}, "children": []}, {"text": u"Firefox 5.0", "selected": False, "urlparams": {"appver": "5.0"}, "children": []}, ], ) eq_( self.check_appver_filters("99999999", "99999999.0"), [ { "text": u"Firefox 99999999.0", "selected": True, "urlparams": {"appver": "99999999.0"}, "children": [], }, {"text": u"Firefox 5.0", "selected": False, "urlparams": {"appver": "5.0"}, "children": []}, ], )
def check_appver_filters(self, appver, expected): request = RequestFactory() request.APP = amo.FIREFOX facets = { u'platforms': [{ u'count': 58, u'term': 1 }], u'appversions': [{ u'count': 58, u'term': 5000000200100 }], u'categories': [{ u'count': 55, u'term': 1 }], u'tags': [] } versions = version_sidebar(request, {'appver': floor_version(appver)}, facets) all_ = versions.pop(0) eq_(all_.text, 'Any %s' % unicode(request.APP.pretty)) eq_(all_.selected, not expected) return [v.__dict__ for v in versions]
def check_appver_filters(self, appver, expected): request = RequestFactory() request.GET = {} request.APP = amo.FIREFOX facets = { u'platforms': [{ u'count': 58, u'term': 1 }], u'appversions': [{ u'count': 58, u'term': 5000000200100 }], u'categories': [{ u'count': 55, u'term': 1 }], u'tags': [] } versions = version_sidebar(request, {'appver': floor_version(appver)}, facets) all_ = versions.pop(0) eq_(all_.text, 'Any %s' % unicode(request.APP.pretty)) eq_(all_.selected, not expected) return [v.__dict__ for v in versions]
def test_appver_long(self): too_big = vnum(vint(MAXVERSION + 1)) just_right = vnum(vint(MAXVERSION)) assert self.check_appver_filters(too_big, floor_version(just_right)), ( 'All I ask is do not crash') eq_(self.check_appver_filters('9999999', '9999999.0'), [{'text': u'Firefox 9999999.0', 'selected': True, 'urlparams': {'appver': '9999999.0'}, 'children': []}, {'text': u'Firefox 5.0', 'selected': False, 'urlparams': {'appver': '5.0'}, 'children': []}]) eq_(self.check_appver_filters('99999999', '99999999.0'), [{'text': u'Firefox 99999999.0', 'selected': True, 'urlparams': {'appver': '99999999.0'}, 'children': []}, {'text': u'Firefox 5.0', 'selected': False, 'urlparams': {'appver': '5.0'}, 'children': []}])
def reporter_detail(request, guid): qs = CompatReport.objects.filter(guid=guid) form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo.utils.paginate(request, qs.order_by('-created'), 100) addon = Addon.objects.filter(guid=guid) name = addon[0].name if addon else guid return jingo.render( request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def reporter_detail(request, guid): qs = CompatReport.objects.filter(guid=guid) form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo.utils.paginate(request, qs.order_by('-created'), 100) addon = Addon.objects.filter(guid=guid) name = addon[0].name if addon else guid return jingo.render(request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def check_appver_filters(self, appver, expected): request = RequestFactory() request.APP = amo.FIREFOX facets = { u"platforms": [{u"count": 58, u"term": 1}], u"appversions": [{u"count": 58, u"term": 5000000200100}], u"categories": [{u"count": 55, u"term": 1}], u"tags": [], } versions = version_sidebar(request, {"appver": floor_version(appver)}, facets) all_ = versions.pop(0) eq_(all_.text, "Any %s" % unicode(request.APP.pretty)) eq_(all_.selected, not expected) return [v.__dict__ for v in versions]
def reporter_detail(request, guid): try: addon = Addon.with_unlisted.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) if (addon and not addon.is_listed and not owner_or_unlisted_reviewer(request, addon)): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo.utils.paginate(request, qs.order_by('-created'), 100) return render( request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def reporter_detail(request, guid): try: addon = Addon.with_unlisted.get(guid=guid) except Addon.DoesNotExist: addon = None name = addon.name if addon else guid qs = CompatReport.objects.filter(guid=guid) if (addon and not addon.is_listed and not owner_or_unlisted_reviewer(request, addon)): # Not authorized? Let's pretend this addon simply doesn't exist. name = guid qs = CompatReport.objects.none() form = AppVerForm(request.GET) if request.GET and form.is_valid() and form.cleaned_data['appver']: # Apply filters only if we have a good app/version combination. app, ver = form.cleaned_data['appver'].split('-') app = amo.APP_IDS[int(app)] ver = vdict(floor_version(ver))['major'] # 3.6 => 3 # Ideally we'd have a `version_int` column to do strict version # comparing, but that's overkill for basic version filtering here. qs = qs.filter(app_guid=app.guid, app_version__startswith=str(ver) + '.') works_ = dict(qs.values_list('works_properly').annotate(Count('id'))) works = {'success': works_.get(True, 0), 'failure': works_.get(False, 0)} works_properly = request.GET.get('works_properly') if works_properly: qs = qs.filter(works_properly=works_properly) reports = amo.utils.paginate(request, qs.order_by('-created'), 100) return render(request, 'compat/reporter_detail.html', dict(reports=reports, works=works, works_properly=works_properly, name=name, guid=guid, form=form))
def compatibility_report(index=None): docs = defaultdict(dict) indices = get_indices(index) # Gather all the data for the index. for app in amo.APP_USAGE: versions = [c for c in amo.COMPAT if c['app'] == app.id] log.info(u'Making compat report for %s.' % app.pretty) latest = UpdateCount.objects.aggregate(d=Max('date'))['d'] qs = UpdateCount.objects.filter(addon__appsupport__app=app.id, addon__disabled_by_user=False, addon__status__in=amo.VALID_STATUSES, addon___current_version__isnull=False, date=latest) updates = dict(qs.values_list('addon', 'count')) for chunk in amo.utils.chunked(updates.items(), 50): chunk = dict(chunk) for addon in Addon.objects.filter(id__in=chunk): doc = docs[addon.id] doc.update(id=addon.id, slug=addon.slug, guid=addon.guid, binary=addon.binary_components, name=unicode(addon.name), created=addon.created, current_version=addon.current_version.version, current_version_id=addon.current_version.pk) doc['count'] = chunk[addon.id] doc.setdefault('top_95', defaultdict(lambda: defaultdict(dict))) doc.setdefault('top_95_all', {}) doc.setdefault('usage', {})[app.id] = updates[addon.id] doc.setdefault('works', {}).setdefault(app.id, {}) # Populate with default counts for all app versions. for ver in versions: doc['works'][app.id][vint(ver['main'])] = { 'success': 0, 'failure': 0, 'total': 0, 'failure_ratio': 0.0, } # Group reports by `major`.`minor` app version. reports = (CompatReport.objects.filter( guid=addon.guid, app_guid=app.guid).values_list( 'app_version', 'works_properly').annotate(Count('id'))) for ver, works_properly, cnt in reports: ver = vint(floor_version(ver)) major = [ v['main'] for v in versions if vint(v['previous']) < ver <= vint(v['main']) ] if major: w = doc['works'][app.id][vint(major[0])] # Tally number of success and failure reports. w['success' if works_properly else 'failure'] += cnt w['total'] += cnt # Calculate % of incompatibility reports. w['failure_ratio'] = w['failure'] / float(w['total']) if app not in addon.compatible_apps: continue compat = addon.compatible_apps[app] d = { 'min': compat.min.version_int, 'max': compat.max.version_int } doc.setdefault('support', {})[app.id] = d doc.setdefault('max_version', {})[app.id] = compat.max.version total = sum(updates.values()) # Remember the total so we can show % of usage later. compat_total, created = CompatTotals.objects.safer_get_or_create( app=app.id, defaults={'total': total}) if not created: compat_total.update(total=total) # Figure out which add-ons are in the top 95% for this app. running_total = 0 for addon, count in sorted(updates.items(), key=lambda x: x[1], reverse=True): running_total += count docs[addon]['top_95_all'][app.id] = running_total < (.95 * total) # Mark the top 95% of add-ons compatible with the previous version for each # app + version combo. for compat in amo.COMPAT: app, ver = compat['app'], vint(compat['previous']) # Find all the docs that have a max_version compatible with ver. supported = [ doc for doc in docs.values() if app in doc.get('support', {}) and doc['support'][app]['max'] >= ver ] # Sort by count so we can get the top 95% most-used add-ons. supported = sorted(supported, key=lambda d: d['count'], reverse=True) total = sum(doc['count'] for doc in supported) # Figure out which add-ons are in the top 95% for this app + version. running_total = 0 for doc in supported: running_total += doc['count'] doc['top_95'][app][ver] = running_total < (.95 * total) # Send it all to the index. for chunk in amo.utils.chunked(docs.values(), 150): for doc in chunk: for index in indices: AppCompat.index(doc, id=doc['id'], refresh=False, index=index) es = amo.search.get_es() es.indices.refresh()
def test_appver_long(self): too_big = vnum(vint(MAXVERSION + 1)) just_right = vnum(vint(MAXVERSION)) self.check_appver_filters(too_big, floor_version(just_right)) self.check_appver_filters("9999999", "9999999.0") self.check_appver_filters("99999999", "99999999.0")
def clean_appver(self): return floor_version(self.cleaned_data.get('appver'))
def test_appver_long(self): too_big = vnum(vint(MAXVERSION + 1)) just_right = vnum(vint(MAXVERSION)) self.check_appver_filters(too_big, floor_version(just_right)) self.check_appver_filters('9999999', '9999999.0') self.check_appver_filters('99999999', '99999999.0')
def compatibility_report(index=None, aliased=True): docs = defaultdict(dict) indices = get_indices(index) # Gather all the data for the index. for app in amo.APP_USAGE: versions = [c for c in settings.COMPAT if c['app'] == app.id] log.info(u'Making compat report for %s.' % app.pretty) latest = UpdateCount.objects.aggregate(d=Max('date'))['d'] qs = UpdateCount.objects.filter(addon__appsupport__app=app.id, addon__disabled_by_user=False, addon__status__in=amo.VALID_STATUSES, addon___current_version__isnull=False, date=latest) updates = dict(qs.values_list('addon', 'count')) for chunk in amo.utils.chunked(updates.items(), 50): chunk = dict(chunk) for addon in Addon.objects.filter(id__in=chunk): doc = docs[addon.id] doc.update(id=addon.id, slug=addon.slug, guid=addon.guid, self_hosted=addon.is_selfhosted(), binary=addon.binary_components, name=unicode(addon.name), created=addon.created, current_version=addon.current_version.version, current_version_id=addon.current_version.pk) doc['count'] = chunk[addon.id] doc.setdefault('top_95', defaultdict(lambda: defaultdict(dict))) doc.setdefault('top_95_all', {}) doc.setdefault('usage', {})[app.id] = updates[addon.id] doc.setdefault('works', {}).setdefault(app.id, {}) # Populate with default counts for all app versions. for ver in versions: doc['works'][app.id][vint(ver['main'])] = { 'success': 0, 'failure': 0, 'total': 0, 'failure_ratio': 0.0, } # Group reports by `major`.`minor` app version. reports = (CompatReport.objects .filter(guid=addon.guid, app_guid=app.guid) .values_list('app_version', 'works_properly') .annotate(Count('id'))) for ver, works_properly, cnt in reports: ver = vint(floor_version(ver)) major = [v['main'] for v in versions if vint(v['previous']) < ver <= vint(v['main'])] if major: w = doc['works'][app.id][vint(major[0])] # Tally number of success and failure reports. w['success' if works_properly else 'failure'] += cnt w['total'] += cnt # Calculate % of incompatibility reports. w['failure_ratio'] = w['failure'] / float(w['total']) if app not in addon.compatible_apps: continue compat = addon.compatible_apps[app] d = {'min': compat.min.version_int, 'max': compat.max.version_int} doc.setdefault('support', {})[app.id] = d doc.setdefault('max_version', {})[app.id] = compat.max.version total = sum(updates.values()) # Remember the total so we can show % of usage later. compat_total, created = CompatTotals.objects.safer_get_or_create( app=app.id, defaults={'total': total}) if not created: compat_total.update(total=total) # Figure out which add-ons are in the top 95% for this app. running_total = 0 for addon, count in sorted(updates.items(), key=lambda x: x[1], reverse=True): running_total += count docs[addon]['top_95_all'][app.id] = running_total < (.95 * total) # Mark the top 95% of add-ons compatible with the previous version for each # app + version combo. for compat in settings.COMPAT: app, ver = compat['app'], vint(compat['previous']) # Find all the docs that have a max_version compatible with ver. supported = [doc for doc in docs.values() if app in doc.get('support', {}) and doc['support'][app]['max'] >= ver] # Sort by count so we can get the top 95% most-used add-ons. supported = sorted(supported, key=lambda d: d['count'], reverse=True) total = sum(doc['count'] for doc in supported) # Figure out which add-ons are in the top 95% for this app + version. running_total = 0 for doc in supported: running_total += doc['count'] doc['top_95'][app][ver] = running_total < (.95 * total) # Send it all to the index. for chunk in amo.utils.chunked(docs.values(), 150): for doc in chunk: for index in indices: AppCompat.index(doc, id=doc['id'], bulk=True, index=index) elasticutils.get_es().flush_bulk(forced=True)
def c(x, y): eq_(floor_version(x), y)
def test_appver_long(self): too_big = vnum(vint(sys.maxint + 1)) just_right = vnum(vint(sys.maxint)) self.check_appver_filters(too_big, floor_version(just_right)) self.check_appver_filters('9999999', '9999999.0') self.check_appver_filters('99999999', '99999999.0')