diff options
author | Laurent Godard <lgodard.libre@laposte.net> | 2014-10-30 16:29:45 +0100 |
---|---|---|
committer | Matúš Kukan <matus.kukan@collabora.com> | 2014-11-12 09:00:30 +0000 |
commit | 8fa8bb641f63d88e67cafe90f0606905150b644e (patch) | |
tree | b4aaac119dc2c7ced0afd6530d93bf7524e68f07 /bin | |
parent | e65790ddcf90ee243bf74f8f906c7b12a7fda901 (diff) |
Parse perfcheck results
refactoring arguments
process csv file only if newer commits
add columned output
calculate deltas & alert messages
Change-Id: Ib7ba87e9cb55b03ac8665db7a8dc302d2e8611a0
Reviewed-on: https://gerrit.libreoffice.org/12155
Reviewed-by: Matúš Kukan <matus.kukan@collabora.com>
Tested-by: Matúš Kukan <matus.kukan@collabora.com>
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/parse-perfcheck.py | 264 |
1 files changed, 216 insertions, 48 deletions
diff --git a/bin/parse-perfcheck.py b/bin/parse-perfcheck.py index afa22a457b6d..ea74c043461f 100755 --- a/bin/parse-perfcheck.py +++ b/bin/parse-perfcheck.py @@ -7,7 +7,6 @@ import sys import os -import time parseTrigger = "desc: Trigger: Client Request: " parseTotal = "totals: " @@ -15,12 +14,16 @@ parseTotal = "totals: " separator = os.path.sep lastCommitId = "" -needsCsvHeader = True +lastCommitDate = "" +needsCsvHeader = True # needs header in csv file ? yes if new + +colsResult = {} +allTests = [] def processDirectory(rootDir): if needsCsvHeader: - intermediateResult = "lastCommit\ttest name\tfiledatetime\tdump comment\tcount\n" + intermediateResult = "lastCommit\tlastCommitDate\ttest filename\tdump comment\tcount\n" else: intermediateResult = "" @@ -40,86 +43,251 @@ def parseFile(dirname, filename): callgrindFile = open(path,'r') lines = callgrindFile.readlines() - message = "" - total = "" + curTestComment = "" + total = "0" for line in lines: if line.startswith(parseTrigger): - message = line[len(parseTrigger):] + curTestComment = line[len(parseTrigger):].replace("\n","") elif line.startswith(parseTotal): - total = line[len(parseTotal):] + total = line[len(parseTotal):].replace("\n","") callgrindFile.close() - if message == "" and total == "0\n": + if curTestComment == "": + return "" + + if total == "0": # should not occur, btw return "" dirs = dirname.split(separator) currentTest = dirs[-1:] testName = currentTest[0].replace(".test.core","") - message = message.replace("\n","") + if lastCommitId not in colsResult: + colsResult[lastCommitId] = {} + colsResult[lastCommitId]['date'] = lastCommitDate + colsResult[lastCommitId]['values'] = {} - fileDate = time.strftime('%m/%d/%Y %H:%M:%S', time.gmtime(os.path.getmtime(path))) + colsResult[lastCommitId]['values'][curTestComment] = total - result = lastCommitId + "\t" + testName + "\t" + fileDate + "\t" + message + "\t" + total + result = lastCommitId + "\t" + lastCommitDate + "\t" + testName + "\t" + curTestComment + "\t" + total + "\n" return result -def getLastCommitId(): +def getLastCommitInfo(): - stream = os.popen("git log") + stream = os.popen("git log --date=iso") + line = stream.readline() + commitId = line.replace("commit ","").replace("\n","") + line = stream.readline() line = stream.readline() - return line.replace("commit ","").replace("\n","") + commitDate = line.replace("Date: ","").replace("\n","").strip() + + return commitId, commitDate def displayUsage(): - print - print "Parses the callgrind results of make percheck" - print - print "Usage: bin/parse_perfcheck.py [targetFileName = perfcheckResult.csv] [sourceDirectory = ./workdir/CppunitTest]" - print "default assumes running from core root directory" - print + usage = """ + +Parses the callgrind results of make percheck + +Arguments : + + --csv-file\t\t the target CSV file - new or containing previous tests - default : perfcheckResult.csv + --source-directory\t directory containing make perfcheck output - default : ./workdir/CppunitTest + --alert-type\t\t mode for calculating alerts - valid values : previous first + --alert-value\t\t alert threshold in % - default = 10 + + --help\t\t this message + +Columned output is dumped into csv-file + ".col" + +Alerts, if any, are displayed in standard output + +""" + print(usage) + +def analyzeArgs(args): + + isValid = True + + targetFileName = "perfcheckResult.csv" + sourceDirectory = "./workdir/CppunitTest" + alertType = "" + alertValue = 10 + + if "--help" in args: + isValid = False + + if isValid: + + for arg in args[1:]: + + found = False + + if arg.startswith("--csv-file"): + spliter = arg.split("=") + if spliter[1] != "": + targetFileName = spliter[1] + found = True + + elif arg.startswith("--source-directory"): + spliter = arg.split("=") + if spliter[1] != "": + sourceDirectory = spliter[1] + found = True + + elif arg.startswith("--alert-type"): + spliter = arg.split("=") + if spliter[1] in ['previous','first']: + alertType = spliter[1] + found = True + else: + isValid = False + + elif arg.startswith("--alert-value"): + spliter = arg.split("=") + if spliter[1] != "": + alertValue = float(spliter[1]) + found = True + + isValid = isValid and found + + return isValid, targetFileName, sourceDirectory, alertType, alertValue + +def readCsvFile(): + + fileResult = open(targetFileName,'r') + lines = fileResult.readlines() + fileResult.close + + lines = lines[1:] #skip header + + for line in lines: + + if line.strip() != "": # do not process empty lines + + spliter = line.replace('\n','').split('\t') + curId = spliter[0] + curDate = spliter[1] + curTestName = spliter[2] + curTestComment = spliter[3] + curValue = spliter[4] + + if curTestComment not in allTests: + allTests.append(curTestComment) + + if curId not in colsResult: + colsResult[curId] = {} + colsResult[curId]['date'] = curDate + colsResult[curId]['values'] = {} + + colsResult[curId]['values'][curTestComment] = curValue if __name__ == '__main__': #check args + isOk, targetFileName, sourceDirectory, alertType, alertValue = analyzeArgs(sys.argv) - if len(sys.argv) < 3: - if len(sys.argv) == 2: - if sys.argv[1] == "--help": - displayUsage() - sys.exit(1) - else: - targetFileName = sys.argv[1] - sourceDirectory = "./workdir/CppunitTest" - elif len(sys.argv) == 1: - targetFileName = "perfcheckResult.csv" - sourceDirectory = "./workdir/CppunitTest" - else: - displayUsage() - sys.exit(1) - else: - targetFileName = sys.argv[1] - sourceDirectory = sys.argv[2] + if not isOk: + displayUsage() + sys.exit(1) # check if sourceDirectorty exists if not os.path.isdir(sourceDirectory): - print "sourceDirectorty %s not found - Aborting" % (sourceDirectory) + print("sourceDirectory %s not found - Aborting" % (sourceDirectory)) sys.exit(1) + # read the complete CSV file + if os.path.isfile(targetFileName): + readCsvFile() + needsCsvHeader = False + # last commit Id - lastCommitId = getLastCommitId() + lastCommitId, lastCommitDate = getLastCommitInfo() + + # walker through directory + if not lastCommitId in colsResult: + + newResult = processDirectory(sourceDirectory) + + print('\nNew results\n' + newResult) + + # append raw result + with open(targetFileName,'a') as fileResult: + fileResult.write(newResult) + + print("\nCSV file written at " + targetFileName + '\n') + + else: + print("\nCSV file up to date " + targetFileName + '\n') + + + # build columned output + + # header + mLine = '\t'.join(["commit", "date"] + allTests) + '\n' + + alertTest = {} + + for k in colsResult: + + mLine += k + "\t" + colsResult[k]['date'] + "\t" + + for t in allTests: + + if t in colsResult[k]['values']: + mValue= colsResult[k]['values'][t] + + if not t in alertTest: + alertTest[t] = {} + alertTest[t][colsResult[k]['date']] = mValue + + else: + mValue = "" + + mLine += mValue + "\t" + + mLine += "\n" + + # write columned result + with open(targetFileName + '.col','w') as fileResult: + fileResult.write(mLine) + + print("Columned file written at " + targetFileName + '.col\n') + + # check for Alerts + + if alertType == "": + sys.exit(1) + + alertResult = "" + + for t in alertTest: + + testDict = alertTest[t] + + # sort + keylist = sorted(testDict.keys()) + maxVal = float(testDict[keylist[-1]]) + minVal = 0 + + if alertType == "previous": + if len(keylist) > 1: + minVal = float(testDict[keylist[-2]]) - # needs header in csv file ? - needsCsvHeader = not os.path.isfile(targetFileName) + else: + minVal = float(testDict[keylist[0]]) - # call walker - globalResult = processDirectory(sourceDirectory) + if minVal != 0: + delta = 100 * ((maxVal-minVal)/minVal) + else: + delta = 0 - print globalResult + if delta > float(alertValue): + alertResult += t + "\t" + "{:.2f}".format(delta) + " %\n" - # write result - fileResult = open(targetFileName,'a') - fileResult.write(globalResult) - fileResult.close() + if alertResult != "": + print("!!!!!!!! ALERT !!!!!!!\n") + print(alertResult) |