blob: 50ddb76deddd26ea825723ca7d35ecea50cf08b1 [file] [log] [blame]
mblighc6b01ed2006-10-13 17:03:26 +00001#!/usr/bin/python
mbligh74fc0462007-11-05 20:24:17 +00002import os, re, parse, frontend, db, sys, socket, getopt
mblighbc985702007-11-05 20:52:15 +00003from traceback import format_exception
mbligh74fc0462007-11-05 20:24:17 +00004
5usage = """\
6usage: parse
7 [-m] # Send mail for FAILED tests
mblighe8b37a92007-12-19 15:54:11 +00008 [-r] # Reparse the results of a job
mbligh74fc0462007-11-05 20:24:17 +00009 [-o directory] # Specify results directory directly
10 <top level results directory> # Specify top level results directory
11"""
12
mblighbc985702007-11-05 20:52:15 +000013def format_error():
14 t, o, tb = sys.exc_info()
15 trace = format_exception(t, o, tb)
16 # Clear the backtrace to prevent a circular reference
17 # in the heap -- as per tutorial
18 tb = ''
19
20 return ''.join(trace)
21
22
mbligh74fc0462007-11-05 20:24:17 +000023try:
mblighe8b37a92007-12-19 15:54:11 +000024 opts, args = getopt.getopt(sys.argv[1:], "hrmo:l:", ["help"])
mbligh74fc0462007-11-05 20:24:17 +000025except getopt.GetoptError:
26 # print help information and exit:
mblighe8b37a92007-12-19 15:54:11 +000027 print usage,
mbligh74fc0462007-11-05 20:24:17 +000028 sys.exit(2)
29
30if len(sys.argv) < 2:
31 print usage
32 sys.exit(2)
33
34singledir = None
35mailit = False
mblighe8b37a92007-12-19 15:54:11 +000036reparse = False
mblighebdbfe62007-11-29 16:38:27 +000037level = 1
mbligh74fc0462007-11-05 20:24:17 +000038for name, value in opts:
39 if name in ("-h", "--help"):
40 usage()
41 sys.exit()
42 if name == "-m":
43 mailit = True
mblighe8b37a92007-12-19 15:54:11 +000044 if name == "-r":
45 reparse = True
mbligh2c05bce2007-11-26 20:15:58 +000046 if name in ("-o"):
mbligh74fc0462007-11-05 20:24:17 +000047 singledir = value
mbligh2c05bce2007-11-26 20:15:58 +000048 if name in ("-l"):
49 level = int(value)
mbligh74fc0462007-11-05 20:24:17 +000050
mbligh74fc0462007-11-05 20:24:17 +000051if singledir:
52 dir = os.path.abspath(singledir)
mbligh8586dc22007-11-29 18:41:06 +000053 assert os.path.exists(dir)
mbligh2c05bce2007-11-26 20:15:58 +000054 jobs_list = [dir]
mbligh74fc0462007-11-05 20:24:17 +000055else:
56 topdir = os.path.abspath(args[0])
mbligh8586dc22007-11-29 18:41:06 +000057 assert os.path.exists(topdir)
mbligh2c05bce2007-11-26 20:15:58 +000058 jobs_list = [os.path.join(topdir, dir) for dir in os.listdir(topdir)]
mblighbb7b8912006-10-08 03:59:02 +000059
mbligh9ec94852007-10-25 15:24:16 +000060debug = True
61
mbligh74fc0462007-11-05 20:24:17 +000062failcc = ""
mbligh9e7c6d02007-11-26 20:59:45 +000063# The user to notify on job failures - TOOD, pull into the config file
mbligh74fc0462007-11-05 20:24:17 +000064notify_user = None
mblighbb7b8912006-10-08 03:59:02 +000065
mbligh432bad42007-10-09 19:56:07 +000066db = db.db(autocommit=False) # do commits transactionally
mbligh056d0d32006-10-08 22:31:10 +000067
mbligh9ec94852007-10-25 15:24:16 +000068
mbligh74fc0462007-11-05 20:24:17 +000069def mailfailure(jobname, job, mesgtxt):
70 # XXX: Need to insert URL here too (frontend.test.url?)
71 link = "http://" + socket.gethostname() + "/results/" + jobname
72
73 # This looks pretty good on fixed-width-font email reader.
mbligh032c2de2007-11-24 19:20:12 +000074 message_header = "\n%s\n%s\n\n%-12s %-20s %-12s %-10s %s\n" % \
75 ("The following tests FAILED for this job:",
76 link, "Job name", "Kernel", "Test name",
77 "FAIL/WARN", "Failure Reason")
78 message_header += "%-12s %-20s %-12s %-10s %s\n" % \
79 ("========", "======", "=========",
80 "=========", "==============")
mbligh74fc0462007-11-05 20:24:17 +000081
82 subject = "AUTOTEST: FAILED tests from " + " job " + jobname
mbligh9e7c6d02007-11-26 20:59:45 +000083 parse.mail(notify_user, job.user, failcc, subject,
mbligh032c2de2007-11-24 19:20:12 +000084 message_header + mesgtxt)
mbligh74fc0462007-11-05 20:24:17 +000085
86
mblighe8b37a92007-12-19 15:54:11 +000087def dprint(string):
88 if debug:
89 print string
90
91
mbligh9ec94852007-10-25 15:24:16 +000092def do_parse(jobname, path):
mbligh0a498cb2007-11-26 17:34:28 +000093 """
94 Parse a single job. Optionally send email on failure, etc.
95 """
mblighe8b37a92007-12-19 15:54:11 +000096 dprint('\nScanning %s (%s)' % (jobname, path))
97 if reparse and db.find_job(jobname):
98 dprint('! Deleting old copy of job results, to reparse it')
99 db.delete_job(jobname)
100 if db.find_job(jobname): # Job has already been parsed
101 dprint('! Already processed')
mbligh9ec94852007-10-25 15:24:16 +0000102 return
mbligh532cb272007-11-26 18:54:20 +0000103 job = parse.job(path)
mbligh8e1ab172007-09-13 17:29:56 +0000104 if not job:
mblighe8b37a92007-12-19 15:54:11 +0000105 dprint('! Failed to parse job (no status file?)')
mbligh9ec94852007-10-25 15:24:16 +0000106 return
mblighd5c33db2006-10-08 21:34:16 +0000107 if not job.kernel:
mblighe8b37a92007-12-19 15:54:11 +0000108 dprint('! Failed to find kernel for job')
mbligh9ec94852007-10-25 15:24:16 +0000109 return
mblighf54ed2a2007-11-24 19:31:30 +0000110 print '+ Parsing ' + path
mbligh74fc0462007-11-05 20:24:17 +0000111 print '* jobname, kernel version: %s %s' % (jobname, job.kernel.base)
112 mesgtxt = "\n"
mblighe9cf9d42007-08-31 08:56:00 +0000113 for test in job.tests:
mbligh74fc0462007-11-05 20:24:17 +0000114 if not test.subdir:
115 continue
mbligh4a2c61e2007-11-12 22:13:11 +0000116 print "* testname, status, reason: %s %s %s" % \
117 (test.subdir, test.status, test.reason)
mbligh74fc0462007-11-05 20:24:17 +0000118 if re.match(r'(FAIL|WARN)',test.status):
mbligh4a2c61e2007-11-12 22:13:11 +0000119 mesgtxt += "%-12s %-20s %-12s %-10s %s" % \
120 (jobname, job.kernel.base, test.subdir,
121 test.status, test.reason)
mbligh74fc0462007-11-05 20:24:17 +0000122
123 if len(mesgtxt) > 2 and mailit:
mbligh4a2c61e2007-11-12 22:13:11 +0000124 print "Sending email report of FAILURES on %s to %s" % \
125 (jobname, job.user)
mbligh74fc0462007-11-05 20:24:17 +0000126 mailfailure(jobname, job, mesgtxt)
mbligh9ec94852007-10-25 15:24:16 +0000127 db.insert_job(jobname, job)
mblighbc985702007-11-05 20:52:15 +0000128 print "COMMITING"
mbligh432bad42007-10-09 19:56:07 +0000129 db.commit()
mblighfd6682452007-09-30 22:02:02 +0000130
mbligh9ec94852007-10-25 15:24:16 +0000131
mbligh74fc0462007-11-05 20:24:17 +0000132
mbligh2c05bce2007-11-26 20:15:58 +0000133for path in jobs_list:
134 job_elements = path.split('/')[-level:] # last 'level' elements of path
135 jobname = '/'.join(job_elements)
mbligh9ec94852007-10-25 15:24:16 +0000136 machine_list = os.path.join(path, '.machines')
137 if os.path.exists(machine_list):
mbligh0a498cb2007-11-26 17:34:28 +0000138 # This is a multi-machine job
mbligh9ec94852007-10-25 15:24:16 +0000139 for m in open(machine_list, 'r').readlines():
140 machine = m.rstrip()
141 if not machine:
142 continue
143 jobpath = os.path.join(path, machine)
144 jobname = os.path.join(os.path.basename(path), machine)
mblighbc985702007-11-05 20:52:15 +0000145 try:
146 do_parse(jobname, jobpath)
147 except:
148 print format_error()
149 continue
mbligh9ec94852007-10-25 15:24:16 +0000150 else:
mbligh0a498cb2007-11-26 17:34:28 +0000151 # This is a single-machine job
mblighbc985702007-11-05 20:52:15 +0000152 try:
153 do_parse(jobname, path)
154 except:
155 print format_error()
156 continue
mbligh9ec94852007-10-25 15:24:16 +0000157
158
mbligh0a498cb2007-11-26 17:34:28 +0000159# Generate vertical text pngs for pretty display in tables.
160#
mblighbc985702007-11-05 20:52:15 +0000161# rows = db.select('distinct hostname', 'machines', {})
162# machines = [row[0] for row in rows]
163#
164# for machine in machines:
165# dir = os.path.dirname(os.path.abspath(sys.argv[0]))
166# vertical_text = os.path.join(dir, 'vertical_text.py')
167# os.system(vertical_text + ' ' + machine)