blob: 6c5e2af67351aadeb6dcc4c7a28fae522a331bf1 [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
8 [-o directory] # Specify results directory directly
9 <top level results directory> # Specify top level results directory
10"""
11
mblighbc985702007-11-05 20:52:15 +000012def format_error():
13 t, o, tb = sys.exc_info()
14 trace = format_exception(t, o, tb)
15 # Clear the backtrace to prevent a circular reference
16 # in the heap -- as per tutorial
17 tb = ''
18
19 return ''.join(trace)
20
21
mbligh74fc0462007-11-05 20:24:17 +000022try:
mbligh2c05bce2007-11-26 20:15:58 +000023 opts, args = getopt.getopt(sys.argv[1:], "hmo:l:", ["help"])
mbligh74fc0462007-11-05 20:24:17 +000024except getopt.GetoptError:
25 # print help information and exit:
26 usage()
27 sys.exit(2)
28
29if len(sys.argv) < 2:
30 print usage
31 sys.exit(2)
32
33singledir = None
34mailit = False
35for name, value in opts:
36 if name in ("-h", "--help"):
37 usage()
38 sys.exit()
39 if name == "-m":
40 mailit = True
mbligh2c05bce2007-11-26 20:15:58 +000041 if name in ("-o"):
mbligh74fc0462007-11-05 20:24:17 +000042 singledir = value
mbligh2c05bce2007-11-26 20:15:58 +000043 if name in ("-l"):
44 level = int(value)
45 else:
46 level = 1
mbligh74fc0462007-11-05 20:24:17 +000047
mbligh74fc0462007-11-05 20:24:17 +000048if singledir:
49 dir = os.path.abspath(singledir)
mbligh2c05bce2007-11-26 20:15:58 +000050 jobs_list = [dir]
mbligh74fc0462007-11-05 20:24:17 +000051else:
52 topdir = os.path.abspath(args[0])
mbligh2c05bce2007-11-26 20:15:58 +000053 jobs_list = [os.path.join(topdir, dir) for dir in os.listdir(topdir)]
mblighbb7b8912006-10-08 03:59:02 +000054
mbligh9ec94852007-10-25 15:24:16 +000055debug = True
56
mbligh74fc0462007-11-05 20:24:17 +000057failcc = ""
58notify_user = None
mblighbb7b8912006-10-08 03:59:02 +000059
mbligh432bad42007-10-09 19:56:07 +000060db = db.db(autocommit=False) # do commits transactionally
mbligh056d0d32006-10-08 22:31:10 +000061
mbligh9ec94852007-10-25 15:24:16 +000062
mbligh74fc0462007-11-05 20:24:17 +000063def mailfailure(jobname, job, mesgtxt):
64 # XXX: Need to insert URL here too (frontend.test.url?)
65 link = "http://" + socket.gethostname() + "/results/" + jobname
66
67 # This looks pretty good on fixed-width-font email reader.
mbligh032c2de2007-11-24 19:20:12 +000068 message_header = "\n%s\n%s\n\n%-12s %-20s %-12s %-10s %s\n" % \
69 ("The following tests FAILED for this job:",
70 link, "Job name", "Kernel", "Test name",
71 "FAIL/WARN", "Failure Reason")
72 message_header += "%-12s %-20s %-12s %-10s %s\n" % \
73 ("========", "======", "=========",
74 "=========", "==============")
mbligh74fc0462007-11-05 20:24:17 +000075
76 subject = "AUTOTEST: FAILED tests from " + " job " + jobname
mbligh1ca17de2007-11-24 19:21:19 +000077 parse.mail("autotest", job.user, failcc, subject,
mbligh032c2de2007-11-24 19:20:12 +000078 message_header + mesgtxt)
mbligh74fc0462007-11-05 20:24:17 +000079
80
mbligh9ec94852007-10-25 15:24:16 +000081def do_parse(jobname, path):
mbligh0a498cb2007-11-26 17:34:28 +000082 """
83 Parse a single job. Optionally send email on failure, etc.
84 """
mbligh9ec94852007-10-25 15:24:16 +000085 if debug:
mblighf54ed2a2007-11-24 19:31:30 +000086 print '\nScanning %s (%s)' % (jobname, path)
mbligh9ec94852007-10-25 15:24:16 +000087 if db.find_job(jobname): # Job has already been parsed
mbligh994a23d2007-10-25 15:28:58 +000088 if debug:
mbligh74fc0462007-11-05 20:24:17 +000089 print '! Already processed'
mbligh9ec94852007-10-25 15:24:16 +000090 return
mbligh532cb272007-11-26 18:54:20 +000091 job = parse.job(path)
mbligh8e1ab172007-09-13 17:29:56 +000092 if not job:
mbligh994a23d2007-10-25 15:28:58 +000093 if debug:
mblighf54ed2a2007-11-24 19:31:30 +000094 print '! Failed to parse job (no status file?)'
mbligh9ec94852007-10-25 15:24:16 +000095 return
mblighd5c33db2006-10-08 21:34:16 +000096 if not job.kernel:
mbligh994a23d2007-10-25 15:28:58 +000097 if debug:
mblighf54ed2a2007-11-24 19:31:30 +000098 print '! Failed to find kernel for job'
mbligh9ec94852007-10-25 15:24:16 +000099 return
mblighf54ed2a2007-11-24 19:31:30 +0000100 print '+ Parsing ' + path
mbligh74fc0462007-11-05 20:24:17 +0000101 print '* jobname, kernel version: %s %s' % (jobname, job.kernel.base)
102 mesgtxt = "\n"
mblighe9cf9d42007-08-31 08:56:00 +0000103 for test in job.tests:
mbligh74fc0462007-11-05 20:24:17 +0000104 if not test.subdir:
105 continue
mbligh4a2c61e2007-11-12 22:13:11 +0000106 print "* testname, status, reason: %s %s %s" % \
107 (test.subdir, test.status, test.reason)
mbligh74fc0462007-11-05 20:24:17 +0000108 if re.match(r'(FAIL|WARN)',test.status):
mbligh4a2c61e2007-11-12 22:13:11 +0000109 mesgtxt += "%-12s %-20s %-12s %-10s %s" % \
110 (jobname, job.kernel.base, test.subdir,
111 test.status, test.reason)
mbligh74fc0462007-11-05 20:24:17 +0000112
113 if len(mesgtxt) > 2 and mailit:
mbligh4a2c61e2007-11-12 22:13:11 +0000114 print "Sending email report of FAILURES on %s to %s" % \
115 (jobname, job.user)
mbligh74fc0462007-11-05 20:24:17 +0000116 mailfailure(jobname, job, mesgtxt)
mbligh9ec94852007-10-25 15:24:16 +0000117 db.insert_job(jobname, job)
mblighbc985702007-11-05 20:52:15 +0000118 print "COMMITING"
mbligh432bad42007-10-09 19:56:07 +0000119 db.commit()
mblighfd6682452007-09-30 22:02:02 +0000120
mbligh9ec94852007-10-25 15:24:16 +0000121
mbligh74fc0462007-11-05 20:24:17 +0000122
mbligh2c05bce2007-11-26 20:15:58 +0000123for path in jobs_list:
124 job_elements = path.split('/')[-level:] # last 'level' elements of path
125 jobname = '/'.join(job_elements)
mbligh9ec94852007-10-25 15:24:16 +0000126 machine_list = os.path.join(path, '.machines')
127 if os.path.exists(machine_list):
mbligh0a498cb2007-11-26 17:34:28 +0000128 # This is a multi-machine job
mbligh9ec94852007-10-25 15:24:16 +0000129 for m in open(machine_list, 'r').readlines():
130 machine = m.rstrip()
131 if not machine:
132 continue
133 jobpath = os.path.join(path, machine)
134 jobname = os.path.join(os.path.basename(path), machine)
mblighbc985702007-11-05 20:52:15 +0000135 try:
136 do_parse(jobname, jobpath)
137 except:
138 print format_error()
139 continue
mbligh9ec94852007-10-25 15:24:16 +0000140 else:
mbligh0a498cb2007-11-26 17:34:28 +0000141 # This is a single-machine job
mblighbc985702007-11-05 20:52:15 +0000142 try:
143 do_parse(jobname, path)
144 except:
145 print format_error()
146 continue
mbligh9ec94852007-10-25 15:24:16 +0000147
148
mbligh0a498cb2007-11-26 17:34:28 +0000149# Generate vertical text pngs for pretty display in tables.
150#
mblighbc985702007-11-05 20:52:15 +0000151# rows = db.select('distinct hostname', 'machines', {})
152# machines = [row[0] for row in rows]
153#
154# for machine in machines:
155# dir = os.path.dirname(os.path.abspath(sys.argv[0]))
156# vertical_text = os.path.join(dir, 'vertical_text.py')
157# os.system(vertical_text + ' ' + machine)