From 1460ce948f73cafa54fee7e754da7bb0920522e0 Mon Sep 17 00:00:00 2001 From: Murali Nandigama Date: Thu, 15 Apr 2010 17:13:29 -0700 Subject: [PATCH] parametrized front end --- unittest-logs/unittest-log.py | 20 +++--- unittest-logs/unittestweb/templates/base.html | 22 +++--- .../templates/viewer/failswindow.html | 2 +- .../unittestweb/templates/viewer/latest.html | 4 +- .../unittestweb/templates/viewer/tests.html | 2 +- .../templates/viewer/topfails.html | 2 +- unittest-logs/unittestweb/urls.py | 26 ++++--- unittest-logs/unittestweb/viewer/models.py | 18 ++--- unittest-logs/unittestweb/viewer/views.py | 70 ++++++++----------- 9 files changed, 75 insertions(+), 91 deletions(-) diff --git a/unittest-logs/unittest-log.py b/unittest-logs/unittest-log.py index d2d0173..19a7d38 100755 --- a/unittest-logs/unittest-log.py +++ b/unittest-logs/unittest-log.py @@ -363,7 +363,7 @@ while curtime < endtime and chunk < totalchunks: continue # we only care about unit test boxes - unittest_indices = [tboxdata['build_name_index'][x] for x in tboxdata['build_name_index'] if re.search("test|xpc", x)] + unittest_indices = [tboxdata['build_name_index'][x] for x in tboxdata['build_name_index'] if re.search("test|xpc|check", x)] # read build table # 'TestFailed' expected log format is "result | test | optional text". testfailedRe = re.compile(r"(TEST-UNEXPECTED-.*) \| (.*) \|(.*)") @@ -406,7 +406,7 @@ while curtime < endtime and chunk < totalchunks: pass # Parse log to save 'TestFailed' results. - elif status == BuildStatus.TestFailed or status == BuildStatus.Burning or status == BuildStatus.Burning: + elif status == BuildStatus.TestFailed : logging.info("Checking build log for '%s' at %d (%s)" % (name, starttime, ctime(starttime))) try: # Grab the build log. @@ -433,14 +433,14 @@ while curtime < endtime and chunk < totalchunks: logging.error("Unexpected error: %s" % sys.exc_info()[0]) #XXX: handle me? - ## Ignore 'Burning' builds: tests may have run nontheless, but it's safer to discard them :-| - #elif status == BuildStatus.Burning: - # continue - # - ## Ignore 'Exception' builds: should only be worse than 'Burning'. - ## (Don't know much at time of writing, since this feature is not active yet: see bug 476656 and follow-ups.) - #elif status == BuildStatus.Exception: - # continue + # Ignore 'Burning' builds: tests may have run nontheless, but it's safer to discard them :-| + elif status == BuildStatus.Burning: + continue + + # Ignore 'Exception' builds: should only be worse than 'Burning'. + # (Don't know much at time of writing, since this feature is not active yet: see bug 476656 and follow-ups.) + elif status == BuildStatus.Exception: + continue # Save 'Unknown' status failure: this should not happen (unless new statuses are created), but we want to know if it does. elif status == BuildStatus.Unknown: diff --git a/unittest-logs/unittestweb/templates/base.html b/unittest-logs/unittestweb/templates/base.html index 2384d6e..7c26bcb 100755 --- a/unittest-logs/unittestweb/templates/base.html +++ b/unittest-logs/unittestweb/templates/base.html @@ -87,23 +87,23 @@ function MyTip(arg) - - - - - + + + + +
Firefox Logo
Mozilla Tinderbox Topfails Dashboard
- + + + + + +
diff --git a/unittest-logs/unittestweb/templates/viewer/failswindow.html b/unittest-logs/unittestweb/templates/viewer/failswindow.html index 4c6647c..5895f00 100644 --- a/unittest-logs/unittestweb/templates/viewer/failswindow.html +++ b/unittest-logs/unittestweb/templates/viewer/failswindow.html @@ -4,7 +4,7 @@ {% for f in failures %} - + {% endfor %}
CountTest name
{{ f.0 }}{{ f.1 }}
{{ f.count }}{{ f.name }}
{% endblock %} diff --git a/unittest-logs/unittestweb/templates/viewer/latest.html b/unittest-logs/unittestweb/templates/viewer/latest.html index ff2fdd9..641d6b9 100755 --- a/unittest-logs/unittestweb/templates/viewer/latest.html +++ b/unittest-logs/unittestweb/templates/viewer/latest.html @@ -7,8 +7,8 @@

Most recent test failures

diff --git a/unittest-logs/unittestweb/templates/viewer/tests.html b/unittest-logs/unittestweb/templates/viewer/tests.html index 04bdb22..bc2274a 100755 --- a/unittest-logs/unittestweb/templates/viewer/tests.html +++ b/unittest-logs/unittestweb/templates/viewer/tests.html @@ -8,7 +8,7 @@

All known failing tests

{% endblock %} diff --git a/unittest-logs/unittestweb/templates/viewer/topfails.html b/unittest-logs/unittestweb/templates/viewer/topfails.html index d5bd477..a086450 100755 --- a/unittest-logs/unittestweb/templates/viewer/topfails.html +++ b/unittest-logs/unittestweb/templates/viewer/topfails.html @@ -4,7 +4,7 @@ {% for f in failures %} - + {% endfor %}
CountTest name
{{ f.0 }}{{ f.1 }}
{{ f.count }}{{ f.name}}
{% endblock %} diff --git a/unittest-logs/unittestweb/urls.py b/unittest-logs/unittestweb/urls.py index 103516e..7a66db2 100755 --- a/unittest-logs/unittestweb/urls.py +++ b/unittest-logs/unittestweb/urls.py @@ -5,18 +5,16 @@ from django.contrib import admin admin.autodiscover() urlpatterns = patterns('unittestweb.viewer.views', - (r'^$', 'index'), - (r'^/$', 'index'), - (r'^trees$', 'trees'), - (r'^trees/(?P.+)$', 'tree'), - (r'^changesets$', 'changesets'), - (r'^changesets/(?P[a-f0-9]+)$', 'changeset'), - (r'^tests$', 'tests'), - (r'^test$', 'test'), - (r'^timeline$', 'timeline'), - (r'^topfails$', 'topfails'), - (r'^failswindow$','failswindow'), - (r'^latest$','latest'), - (r'^Help$','Help'), - (r'^base$','base'), + #url(r'^(?P.+)?$', 'latest', name='index'), + url(r'^trees/(?P.+)?$','trees', name='trees'), + url(r'^tree/(?P.+)?$','tree', name='tree'), + url(r'^changesets/(?P.+)?$','changesets', name='changesets'), + url(r'^changesets/(?P.+)/(?P[a-f0-9]+)$', 'changeset', name='changeset'), + url(r'^tests/(?P.+)?$','tests', name='tests'), + url(r'^test/(?P.+)?$','test', name='test'), + url(r'^timeline/(?P.+)?$','timeline', name='timeline'), + url(r'^topfails/(?P.+)?$','topfails', name='topfails'), + url(r'^failswindow/(?P.+)?$','failswindow', name='failswindow'), + url(r'^latest/(?P.+)?$','latest', name='latest'), + url(r'^Help/(?P.+)?$','Help', name='Help'), ) diff --git a/unittest-logs/unittestweb/viewer/models.py b/unittest-logs/unittestweb/viewer/models.py index 144a8fe..29e55bd 100755 --- a/unittest-logs/unittestweb/viewer/models.py +++ b/unittest-logs/unittestweb/viewer/models.py @@ -75,13 +75,10 @@ class Tests(models.Model): class Meta: db_table = 'tests' -def get_most_failing_tests(): - cursor = connection.cursor() - cursor.execute("select count(*), name from (select builds.id, name from builds inner join tests on builds.id = tests.buildid group by builds.id, name) aaa group by name order by count(*) desc limit 25") - for row in cursor: - yield row +def get_most_failing_tests(tree): + return Tests.objects.filter(build__tree__name=tree).values('name').annotate(count=models.Count('name')).order_by('-count') -def get_fails_in_timerange(self): +def get_fails_in_timerange(self,tree): # Get current time, in seconds. endtime = int(time()) @@ -100,10 +97,7 @@ def get_fails_in_timerange(self): 'h': 3600}[m.group(2)] # Set current time to beginning of requested timespan ending now. curtime = endtime - timespan - #print curtime, timespan, endtime-curtime - cursor = connection.cursor() - statement = "select count(*), name from (select builds.id, name from builds inner join tests on builds.id = tests.buildid where builds.starttime >"+str(curtime)+" group by builds.id, name) aaa group by name order by count(*) DESC" - cursor.execute(statement) - for row in cursor: - yield row + qs = get_most_failing_tests(tree) + return qs.filter(build__starttime__gt=curtime) + diff --git a/unittest-logs/unittestweb/viewer/views.py b/unittest-logs/unittestweb/viewer/views.py index e3079ba..a773372 100755 --- a/unittest-logs/unittestweb/viewer/views.py +++ b/unittest-logs/unittestweb/viewer/views.py @@ -4,69 +4,61 @@ import re from django.http import HttpResponse import json -def index(request): - return render_to_response('viewer/index.html') - -def latest(request): - if request.GET.has_key('tree'): - tree =request.GET['tree'] - failures = get_list_or_404(Tests.objects.all().order_by('-build__starttime')[:10]) +def latest(request,tree='Firefox'): + failures = get_list_or_404(Tests.objects.filter(build__tree__name=tree).order_by('-build__starttime'))[:10] if request.GET.has_key('json'): jtext = [{"Test_name":f.name, "Build_status":f.build.status, "Logfile": f.build.tinderbox_link(),"Changeset":f.build.json_changeset_link() , "Failure_description":f.description} for f in failures] return HttpResponse(json.dumps(jtext)) else: - return render_to_response('viewer/latest.html', {'failures': failures}) + return render_to_response('viewer/latest.html', {'failures': failures, 'tree' : tree}) -def index(request): - failures = get_list_or_404(Tests.objects.all().order_by('-build__starttime')[:10]) - return render_to_response('viewer/index.html', {'failures': failures}) - -def base(request): - return render_to_response('viewer/base.html') +def index(request,tree='Firefox'): + failures = get_list_or_404(Tests.objects.filter(build__tree__name=tree).order_by('-build__starttime')[:10]) + return render_to_response('viewer/index.html', {'failures': failures, 'tree' : tree}) -def trees(request): +def trees(request,tree='Firefox'): alltrees = Trees.objects.all().order_by('name') - return render_to_response('viewer/trees.html', {'trees': alltrees}) + return render_to_response('viewer/trees.html', {'trees': alltrees , 'tree' : tree}) -def tree(request, tree): +def tree(request, tree='Firefox'): newestbuilds = get_list_or_404(Builds.objects.filter(tree__name__exact=tree).order_by('-starttime')[:5]) return render_to_response('viewer/tree.html', {'tree': tree, 'newestbuilds': newestbuilds}) -def changesets(request): - build_csets = Builds.objects.values('changeset').distinct() - return render_to_response('viewer/changesets.html', {'changesets': [b['changeset'] for b in build_csets]}) +def changesets(request,tree='Firefox'): + build_csets = Builds.objects.filter(tree__name__exact=tree).values('changeset').distinct() + return render_to_response('viewer/changesets.html', { 'tree' : tree,'changesets': [b['changeset'] for b in build_csets]}) -def changeset(request, changeset): +def changeset(request, changeset,tree='Firefox'): builds = get_list_or_404(Builds, changeset__exact=changeset) - return render_to_response('viewer/changeset.html', {'changeset': changeset, 'builds': builds}) + return render_to_response('viewer/changeset.html', {'changeset': changeset, 'builds': builds, 'tree' : tree}) -def tests(request): - test_names = Tests.objects.values('name').distinct() +def tests(request,tree='Firefox'): + test_names = Tests.objects.filter(build__tree__name__exact=tree).values('name').distinct() if request.GET.has_key('json'): jtext = list(test_names) return HttpResponse(json.dumps(jtext)) else: - return render_to_response('viewer/tests.html', {'tests': [t['name'] for t in test_names]}) + return render_to_response('viewer/tests.html', { 'tree' : tree, 'tests': [t['name'] for t in test_names]}) -def test(request): - failures = get_list_or_404(Tests.objects.filter(name__exact=request.GET['name']).order_by('-build__starttime')) - return render_to_response('viewer/test.html', {'test': request.GET['name'], 'failures': failures}) +def test(request,tree='Firefox'): + failures = get_list_or_404(Tests.objects.filter(build__tree__name__exact=tree).filter(name__exact=request.GET['name']).order_by('-build__starttime')) + return render_to_response('viewer/test.html', {'test': request.GET['name'], 'failures': failures, 'tree' : tree}) -def topfails(request): - failures = get_most_failing_tests() +def topfails(request,tree='Firefox'): + failures = get_most_failing_tests(tree)[:25] if request.GET.has_key('json'): jtext = list(failures) return HttpResponse(json.dumps(jtext)) else: - return render_to_response('viewer/topfails.html', {'failures': failures}) + return render_to_response('viewer/topfails.html', {'failures': failures, 'tree' : tree}) -def Help(request): - return render_to_response('viewer/Help.html') +def Help(request,tree): + return render_to_response('viewer/Help.html',{'tree':tree}) -def timeline(request): +def timeline(request,tree='Firefox'): name = request.GET['name'] - builds = get_list_or_404(Builds, tests__name__exact=name) + builds = get_list_or_404(Builds.objects.filter(tree__name__exact=tree), tests__name__exact=name) buildlist = [] desc_list = [] for b in builds: @@ -83,12 +75,12 @@ def timeline(request): }) return render_to_response('viewer/timeline.html', {'test': name, 'descriptions': desc_list, - 'builds': buildlist}) + 'builds': buildlist, 'tree' : tree}) -def failswindow(request): +def failswindow(request,tree='Firefox'): period=request.GET['window'] m = re.match("(\d+)([ymwdh])", period) - failures = get_fails_in_timerange(period) + failures = get_fails_in_timerange(period,tree) if request.GET.has_key('json'): jtext = list(failures) return HttpResponse(json.dumps(jtext)) @@ -107,5 +99,5 @@ def failswindow(request): prd = 'days' - return render_to_response('viewer/failswindow.html', {'failures': failures,'n':m.group(1),'d':prd}) + return render_to_response('viewer/failswindow.html', {'failures': failures,'n':m.group(1),'d':prd, 'tree' : tree})