import sys
import os
def printHelp():
print("{}: OUTFILE.xml MEMSCRIPT.log [MEMSCRIPT.log]*".format(sys.argv[0]))
def validLogfile(logfile):
f = open(logfile)
valid = False
for line in f:
if "MemoryScape Script Log File" in line or "TotalView Debugger Script Log File" in line:
valid = True
break
f.close()
return valid
def processHeader(logfile):
header = {}
f = open(logfile)
for line in f:
if "* Date:" in line:
header["date"] = line.split()[2]
elif "* Target:" in line:
header["target"] = line.split()[2]
f.close()
return header
def processErrorNotifications(logfile):
errorText = ""
inErrorText = False
f = open(logfile)
for line in f:
if "! Process Error Notification" in line:
errorText = line
inErrorText = True
continue
elif inErrorText and "!!!!!" in line:
# We are done with the Error Notification section
inErrorText = False
break
elif inErrorText:
errorText = errorText + line
f.close()
return errorText
def getReplayRecordingFile(logfile):
# Return the name of the recording file if one was generated
recordingFile = ""
f = open(logfile)
for line in f:
if "Saving replay recording file to file" in line:
# A recording file was saved, pick it up
recordingFile = line.split("Saving replay recording file to file ")[1].strip()
break
f.close()
return recordingFile
def processLogfile(f, logfile):
# Pick up the header information from the logfile
header = processHeader(logfile)
# Pick up if an error was detected
errorText = processErrorNotifications(logfile)
# Pick up there was a recording file generated
recordingFile = getReplayRecordingFile(logfile)
print("Recording file: {}".format(recordingFile))
# Recording files will be reported as attachments to JUnit using the
# JUnit Attachments plugin. This plugin requires use of the
# classname attribute for each testcase in order to associate each
# attachment. Each attachment must appear in a directory with the
# same name as the classname. Recording files can be big so we'll
# simply create a link to the original file from the classname directory.
recordingsDir = "recordings"
# We'll use classname "recordings". Create a directory that matches
# the classname.
if not os.path.exists(recordingsDir):
os.mkdir(recordingsDir)
# Link the original file into the recordings directory
srcFile = "{}/{}".format(os.getcwd(), recordingFile)
destFile = "{}/{}/{}".format(os.getcwd(), recordingsDir, recordingFile)
if not os.path.exists(destFile):
os.symlink(srcFile, destFile)
# Generate an ATTATCHMENT statement that JUnit Attachments plugin will
# pick up
#print("[[ATTACHMENT|{}/{}]]".format(os.getcwd(), recordingFile))
f.write(" \n"
.format(header["target"]))
if errorText:
f.write(" \n".format(header["target"]))
f.write("\n")
f.write(" \n")
f.write(" \n")
print("Generated testcase for logfile {}.".format(logfile))
def analyzeLogfiles(logfiles):
invalid = failures = 0
for logfile in logfiles:
# Is the log file valid?
if not validLogfile(logfile):
invalid = invalid + 1
continue
# Pick up information from the "MemoryScape Script Log File"/header section
header = processHeader(logfile)
print("Header[\"date\"]: {}".format(header["date"]))
print("Header[\"target\"]: {}".format(header["target"]))
# Keep track of the number of files
errorText = processErrorNotifications(logfile)
if errorText:
failures = failures + 1
return invalid, failures
def processLogfiles(outfile, logfiles):
# Store summary information in a dictionary
script_info = {}
# Phase 1 - Determine the number of invalid log files and failures
script_info["invalid_logfiles"], script_info["failures"] = analyzeLogfiles(logfiles)
print "Phase 1: {}".format(script_info)
# Write the header for the XML file
f = open(outfile, "w")
f.write('\n')
f.write("\n".format(script_info["failures"], script_info["failures"]))
f.write(" \n".format(script_info["failures"], script_info["failures"]))
for logfile in logfiles:
if not validLogfile(logfile):
print("Skipping invalid tvscript log file: {}".format(logfile))
continue
print("Processing script log file: {}".format(logfile))
processLogfile(f, logfile)
f.write(" \n")
f.write("\n")
f.close()
print("Generated JUnit XML file: {}".format(outfile))
return True
def main():
if len(sys.argv) < 3:
printHelp()
sys.exit("ERROR")
outfile = sys.argv[1]
logfiles = sys.argv[2:]
processLogfiles(outfile, logfiles)
if __name__ == '__main__':
main()