cleanup/restore
This commit is contained in:
0
topfails/viewer/__init__.py
Normal file
0
topfails/viewer/__init__.py
Normal file
115
topfails/viewer/models.py
Normal file
115
topfails/viewer/models.py
Normal file
@@ -0,0 +1,115 @@
|
||||
import re
|
||||
from django.db import models, connection
|
||||
from datetime import datetime
|
||||
from time import ctime, sleep, time
|
||||
|
||||
class OS():
|
||||
Windows = 0
|
||||
Mac = 1
|
||||
Linux = 2
|
||||
Unknown = 3
|
||||
|
||||
OS_CHOICES = (
|
||||
(OS.Windows, 'Windows'),
|
||||
(OS.Mac, 'Mac'),
|
||||
(OS.Linux, 'Linux'),
|
||||
(OS.Unknown, 'Unknown')
|
||||
)
|
||||
|
||||
class BuildStatus():
|
||||
Success = 0
|
||||
TestFailed = 1
|
||||
Burning = 2
|
||||
Exception = 3
|
||||
Unknown = 4
|
||||
|
||||
BUILDSTATUS_CHOICES = (
|
||||
(BuildStatus.Success, 'Success'),
|
||||
(BuildStatus.TestFailed, 'Test Failed'),
|
||||
(BuildStatus.Burning, 'Burning'),
|
||||
(BuildStatus.Exception, 'Exception'),
|
||||
(BuildStatus.Unknown, 'Unknown')
|
||||
)
|
||||
|
||||
|
||||
class Tree(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=45, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Build(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
os = models.IntegerField(choices=OS_CHOICES)
|
||||
tree = models.ForeignKey(Tree)
|
||||
starttime = models.IntegerField(null=True, blank=True)
|
||||
status = models.IntegerField(choices=BUILDSTATUS_CHOICES)
|
||||
changeset = models.CharField(max_length=80,blank=True)
|
||||
logfile = models.CharField(max_length=300,blank=True)
|
||||
|
||||
def startdate(self):
|
||||
return datetime.fromtimestamp(self.starttime)
|
||||
|
||||
def changesetlink(self):
|
||||
if str(self.tree) == 'Firefox':
|
||||
return '<a href="%s/rev/%s">%s</a>' % ("http://hg.mozilla.org/mozilla-central", self.changeset, self.changeset)
|
||||
elif str(self.tree) == 'Firefox3.6':
|
||||
return '<a href="%s/rev/%s">%s</a>' % ("http://hg.mozilla.org/releases/mozilla-1.9.2", self.changeset, self.changeset)
|
||||
elif str(self.tree) == 'Thunderbird' or str(self.tree) == 'SeaMonkey':
|
||||
return '<a href="%s/rev/%s">%s</a>' % ("http://hg.mozilla.org/comm-central", self.changeset, self.changeset)
|
||||
else :
|
||||
return '<a href="%s/rev/%s">%s</a>' % ("http://hg.mozilla.org/mozilla-central", self.changeset, self.changeset)
|
||||
|
||||
def jsonchangesetlink(self):
|
||||
return "%s/rev/%s" % ("http://hg.mozilla.org/mozilla-central", self.changeset)
|
||||
|
||||
def tinderboxlink(self):
|
||||
if self.logfile:
|
||||
return "http://tinderbox.mozilla.org/showlog.cgi?log=%s/%s" % (self.tree.name, self.logfile)
|
||||
return "http://tinderbox.mozilla.org/showbuilds.cgi?tree=%s&maxdate=%d&hours=3" % (self.tree.name, self.starttime)
|
||||
|
||||
|
||||
class Test(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=300, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class TestFailure(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
build = models.ForeignKey(Build)
|
||||
test = models.ForeignKey(Test)
|
||||
failtext = models.CharField(max_length=400, blank=True)
|
||||
|
||||
@classmethod
|
||||
def get_most_failing_tests(cls,tree):
|
||||
return cls.objects.filter(build__tree__name=tree).values('test__name').annotate(count=models.Count('test__name')).order_by('-count')[:25]
|
||||
|
||||
@classmethod
|
||||
def get_time_failing_tests(cls,tree):
|
||||
return cls.objects.filter(build__tree__name=tree).values('test__name').annotate(count=models.Count('test__name')).order_by('-count')
|
||||
|
||||
@classmethod
|
||||
def get_fails_in_timerange(cls,period,tree):
|
||||
|
||||
# Get current time, in seconds.
|
||||
endtime = int(time())
|
||||
|
||||
m = re.match("(\d+)([ymwdh])", period)
|
||||
if m is None:
|
||||
print >>sys.stderr, "ERROR: bad timespan = '%s'!" % options.timespan
|
||||
sys.exit(1)
|
||||
|
||||
timespan = int(m.group(1)) * {'y': 365 * 24 * 3600,
|
||||
'm': 30 * 24 * 3600,
|
||||
'w': 7 * 24 * 3600,
|
||||
'd': 24 * 3600,
|
||||
'h': 3600}[m.group(2)]
|
||||
# Set current time to beginning of requested timespan ending now.
|
||||
curtime = endtime - timespan
|
||||
qs = cls.get_time_failing_tests(tree)
|
||||
return qs.filter(build__starttime__gt=curtime)
|
||||
|
||||
|
||||
107
topfails/viewer/views.py
Normal file
107
topfails/viewer/views.py
Normal file
@@ -0,0 +1,107 @@
|
||||
from django.shortcuts import render_to_response, get_list_or_404
|
||||
from topfails.viewer.models import Build, Tree, Test,TestFailure, OS_CHOICES
|
||||
import re
|
||||
from django.http import HttpResponse
|
||||
import json
|
||||
|
||||
def latest(request,tree='Firefox'):
|
||||
failures = get_list_or_404(TestFailure.objects.filter(build__tree__name=tree).order_by('-build__starttime')[:20])
|
||||
if request.GET.has_key('json'):
|
||||
jtext = [{"testname":f.test.name, "buildstatus":f.build.status, "logfile": f.build.tinderboxlink(),"changeset":f.build.jsonchangesetlink() , "failtext":f.failtext} for f in failures]
|
||||
return HttpResponse(json.dumps(jtext))
|
||||
else:
|
||||
return render_to_response('viewer/latest.html', {'failures': failures, 'tree' : tree})
|
||||
|
||||
def index(request,tree='Firefox'):
|
||||
failures = get_list_or_404(TestFailure.objects.filter(build__tree__name=tree).order_by('-build__starttime')[:20])
|
||||
return render_to_response('viewer/latest.html', {'failures': failures, 'tree' : tree})
|
||||
|
||||
|
||||
def trees(request,tree='Firefox'):
|
||||
alltrees = Tree.objects.all().order_by('name')
|
||||
return render_to_response('viewer/trees.html', {'trees': alltrees , 'tree' : tree})
|
||||
|
||||
def tree(request, tree='Firefox'):
|
||||
newestbuilds = get_list_or_404(Build.objects.filter(tree__name__exact=tree).order_by('-starttime')[:5])
|
||||
return render_to_response('viewer/tree.html', {'tree': tree, 'newestbuilds': newestbuilds})
|
||||
|
||||
def changesets(request,tree='Firefox'):
|
||||
build_csets = Build.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,tree='Firefox'):
|
||||
builds = get_list_or_404(Build, changeset__exact=changeset)
|
||||
return render_to_response('viewer/changeset.html', {'changeset': changeset, 'builds': builds, 'tree' : tree})
|
||||
|
||||
def tests(request,tree='Firefox'):
|
||||
test_names = TestFailure.objects.filter(build__tree__name__exact=tree).values('test__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', { 'tree' : tree, 'tests': [t['test__name'] for t in test_names]})
|
||||
|
||||
def test(request,tree='Firefox'):
|
||||
failures = get_list_or_404(TestFailure.objects.filter(build__tree__name__exact=tree).filter(test__name__exact=request.GET['name']).order_by('-build__starttime')[:10000])
|
||||
#if request.GET.has_key('json'):
|
||||
#jtext = list(failures)
|
||||
#return HttpResponse(json.dumps(jtext))
|
||||
#else:
|
||||
return render_to_response('viewer/test.html', {'test': request.GET['name'], 'failures': failures, 'tree' : tree})
|
||||
|
||||
def topfails(request,tree='Firefox'):
|
||||
failures = TestFailure.get_most_failing_tests(tree)
|
||||
if request.GET.has_key('json'):
|
||||
jtext = list(failures)
|
||||
return HttpResponse(json.dumps(jtext))
|
||||
else:
|
||||
return render_to_response('viewer/topfails.html', {'failures': failures, 'tree' : tree})
|
||||
|
||||
def Help(request,tree):
|
||||
return render_to_response('viewer/Help.html',{'tree':tree})
|
||||
|
||||
def timeline(request,tree='Firefox'):
|
||||
name = request.GET['name']
|
||||
builds = get_list_or_404(Build.objects.filter(tree__name__exact=tree), test__name__exact=name)
|
||||
buildlist = []
|
||||
desc_list = []
|
||||
for b in builds:
|
||||
descs = b.testfailure_set.filter(testfailure__name__exact=name).order_by('id')
|
||||
desc = '\n'.join(descs.values_list('description', flat=True))
|
||||
if desc not in desc_list:
|
||||
desc_list.append(desc)
|
||||
desc_i = desc_list.index(desc)
|
||||
buildlist.append({'build': b,
|
||||
'desctype': desc_i,
|
||||
'description': desc,
|
||||
'os': OS_CHOICES[b.os][1],
|
||||
'time': b.startdate().isoformat() + "Z",
|
||||
})
|
||||
return render_to_response('viewer/timeline.html', {'test': name,
|
||||
'descriptions': desc_list,
|
||||
'builds': buildlist, 'tree' : tree})
|
||||
|
||||
def failswindow(request,tree='Firefox'):
|
||||
period=request.GET['window']
|
||||
m = re.match("(\d+)([ymwdh])", period)
|
||||
failures = TestFailure.get_fails_in_timerange(period,tree)
|
||||
if request.GET.has_key('json'):
|
||||
jtext = list(failures)
|
||||
return HttpResponse(json.dumps(jtext))
|
||||
else:
|
||||
if m.group(2) == 'd':
|
||||
prd='days'
|
||||
elif m.group(2) == 'h':
|
||||
prd = 'hours'
|
||||
elif m.group(2) == 'w':
|
||||
prd = 'weeks'
|
||||
elif m.group(2) == 'm':
|
||||
prd = 'months'
|
||||
elif m.group(2) == 'y':
|
||||
prd = 'years'
|
||||
else:
|
||||
prd = 'days'
|
||||
|
||||
|
||||
return render_to_response('viewer/failswindow.html', {'failures': failures,'n':m.group(1),'d':prd, 'tree' : tree})
|
||||
|
||||
Reference in New Issue
Block a user