blob: 24c8f660e8926c685cca22d811a517ce43eb9f8c [file] [log] [blame]
#!/usr/bin/python
import os, re, md5, sys
valid_users = r'(apw|mbligh|andyw|korgtest)'
build_stock = re.compile('build generic stock (2\.\S+)')
build_url = re.compile('build generic url \S*/linux-(2\.\d\.\d+(\.\d+)?(-rc\d+)?).tar')
valid_kernel= re.compile('2\.\d\.\d+(\.\d+)?(-rc\d+)?(-(git|bk))\d+')
debug = True
def shorten_patch(long):
short = os.path.basename(long)
short = re.sub(r'^patch-', '', short)
short = re.sub(r'\.(bz2|gz)$', '', short)
short = re.sub(r'\.patch$', '', short)
short = re.sub(r'\+', '_', short)
return short
def dprint(info):
if debug:
sys.stderr.write(str(info) + '\n')
class job:
def __init__(self, dir, type):
self.dir = dir
self.type = type
self.control = os.path.join(dir, "control")
self.status = os.path.join(dir, "status")
self.variables = {}
self.tests = []
self.kernel = None
if not os.path.exists(self.status):
return None
# We should really replace this with sysinfo/hostname!
uname = os.path.join(dir, "sysinfo/uname_-a")
try:
self.machine = open(uname, 'r').readline().split()[1]
except:
return None
self.grope_status()
def grope_status(self):
dprint('=====================================================')
dprint(self.dir)
dprint('=====================================================')
self.kernel = kernel(self.dir)
# NOTE: currently we don't cope with nested START / END blocks
group_subdir = None
for line in open(self.status, 'r').readlines():
dprint('STATUS: ' + line.rstrip())
if not re.match(r'\t*\S', line):
continue # ignore continuation lines
if re.match(r'\t*START', line):
group_subdir = None
continue # ignore start lines
reason = None
if line.startswith('END'):
elements = line.split(None, 4)[1:]
else:
elements = line.split(None, 3)
elements.append(None) # in case no reason specified
(status, subdir, testname, reason) = elements[0:4]
################################################
# REMOVE THIS SECTION ONCE OLD FORMAT JOBS ARE GONE
################################################
if re.match(r'(GOOD|FAIL|WARN) ', line):
(status, testname, reason) = line.split(None, 2)
if testname.startswith('kernel.'):
subdir = 'build'
else:
subdir = testname
if testname.startswith('completed'):
raise 'testname is crap'
################################################
if subdir == '----':
subdir = None
if line.startswith('END'):
subdir = group_subdir
if line.startswith('\t'): # we're in a block group
if subdir:
group_subdir = subdir
continue
debug = str((status, subdir, testname, reason))
dprint('GROPE_STATUS: ' + debug)
if not re.match(r'(boot$|kernel\.)', testname):
# This is a real test
if subdir and subdir.count('.'):
# eg dbench.ext3
testname = subdir
self.tests.append(test(subdir, testname, status, reason, self.kernel, self))
dprint('')
class kernel:
def __init__(self, topdir):
self.base = None
self.patches = []
patch_hashes = []
# HACK. we don't have proper build tags in the status file yet
# so we hardcode build/ and do it at the start of the job
builddir = os.path.join(topdir, 'build')
if not os.path.exists(builddir):
uname_file = os.path.join(topdir, 'sysinfo/uname_-a')
uname = open(uname_file, 'r').readline().split()
self.base = uname[2]
else:
log = os.path.join(builddir, 'debug/build_log')
if not os.path.exists(log):
return
for line in open(log, 'r'):
print line
(type, rest) = line.split(': ', 1)
words = rest.split()
if type == 'BASE':
self.base = words[0]
if type == 'PATCH':
print words
self.patches.append(patch(*words[0:]))
# patch_hashes.append(words[2])
if self.base:
self.kernel_hash = self.get_kver_hash(self.base, patch_hashes)
def get_kver_hash(self, base, patch_hashes):
"""\
Calculate a hash representing the unique combination of
the kernel base version plus
"""
key_string = ','.join([base] + patch_hashes)
return md5.new(key_string).hexdigest()
class patch:
def __init__(self, spec, reference=None, hash=None):
# NEITHER OF THE ABOVE SHOULD HAVE DEFAULTS!!!! HACK HACK
if not reference:
reference = spec
print 'PATCH::%s %s %s' % (spec, reference, hash)
self.spec = spec
self.reference = reference
self.hash = hash
class test:
def __init__(self, subdir, testname, status, reason, kernel, job):
self.subdir = subdir
self.testname = testname
self.status = status
self.reason = reason
if subdir:
self.keyval = os.path.join(job.dir, subdir, 'results/keyval')
if not os.path.exists(self.keyval):
self.keyval = None
else:
self.keyval = None
self.iterations = []
self.kernel = kernel
self.machine = job.machine
dprint("PARSING TEST %s %s %s" % (subdir, testname, self.keyval))
if not self.keyval:
return
count = 1
lines = []
for line in open(self.keyval, 'r').readlines():
if not re.search('\S', line): # blank line
self.iterations.append(iteration(count, lines))
lines = []
count += 1
else:
lines.append(line)
if lines:
self.iterations.append(iteration(count, lines))
class iteration:
def __init__(self, index, lines):
self.index = index
self.keyval = {}
dprint("ADDING ITERATION %d" % index)
for line in lines:
(key, value) = line.split('=', 1)
self.keyval[key] = value