Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Tools/Replay/CheckLogs.py
Views: 1798
#!/usr/bin/env python1'''2run Replay over a set of logs to check for code regressions3'''45import optparse, os, sys67parser = optparse.OptionParser("CheckLogs")8parser.add_option("--logdir", type='string', default='testlogs', help='directory of logs to use')9parser.add_option("--create-checked-logs", action='store_true', default=False, help="created logs with CHEK messages")10parser.add_option("--tolerance-euler", type=float, default=3, help="tolerance for euler angles in degrees");11parser.add_option("--tolerance-pos", type=float, default=2, help="tolerance for position angles in meters");12parser.add_option("--tolerance-vel", type=float, default=2, help="tolerance for velocity in meters/second");1314opts, args = parser.parse_args()1516def run_cmd(cmd, dir=".", show=False, output=False, checkfail=True):17'''run a shell command'''18from subprocess import call, check_call,Popen, PIPE19if show:20print("Running: '%s' in '%s'" % (cmd, dir))21if output:22return Popen([cmd], shell=True, stdout=PIPE, cwd=dir).communicate()[0]23elif checkfail:24return check_call(cmd, shell=True, cwd=dir)25else:26return call(cmd, shell=True, cwd=dir)2728def run_replay(logfile):29'''run Replay on one logfile'''30print("Processing %s" % logfile)31cmd = "./Replay.elf -- --check %s --tolerance-euler=%f --tolerance-pos=%f --tolerance-vel=%f " % (32logfile,33opts.tolerance_euler,34opts.tolerance_pos,35opts.tolerance_vel)36run_cmd(cmd, checkfail=False)3738def get_log_list():39'''get a list of log files to process'''40import glob, sys41pattern = os.path.join(opts.logdir, "*-checked.bin")42file_list = glob.glob(pattern)43print("Found %u logs to processs" % len(file_list))44if len(file_list) == 0:45print("No logs to process matching %s" % pattern)46sys.exit(1)47return file_list4849def create_html_results():50'''create a HTML file with results'''51error_count = 05253git_version = run_cmd('git log --pretty=oneline HEAD~1..HEAD', output=True)5455f = open("replay_results.html", "w")56f.write(57'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"58"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">59<html lang="en" xmlns="http://www.w3.org/1999/xhtml">60<head>61<title>Replay results</title>62<meta charset="utf-8"/>63</head>64<body>65<h1>Replay Results</h1>66Git version: %s67<p>68<table border="1">69<tr bgcolor="lightgrey">70<th>Filename</th>71<th>RollError(deg)</th>72<th>PitchError(deg)</th>73<th>YawError(deg)</th>74<th>PosError(m)</th>75<th>VelError(m/s)</th>76</tr>77''' % git_version)78infile = open("replay_results.txt", "r")7980line_count = 081line_errors = 08283for line in infile:84line = line.strip()85line_count += 186a = line.split("\t")87if len(a) != 6:88print("Invalid line: %s" % line)89error_count += 190continue91tolerances = [opts.tolerance_euler,92opts.tolerance_euler,93opts.tolerance_euler,94opts.tolerance_pos,95opts.tolerance_vel]96f.write('''<tr><td><a href="%s">%s</a></td>''' % (a[0],a[0]))97error_in_this_log = False98for i in range(1,6):99tol = tolerances[i-1]100if a[i] == "FPE":101bgcolor = "red"102error_count += 1103error_in_this_log = True104elif float(a[i]) > tol:105bgcolor = "red"106error_count += 1107error_in_this_log = True108else:109bgcolor = "white"110f.write('''<td bgcolor="%s" align="right">%s</td>\n''' % (bgcolor, a[i]))111112if error_in_this_log:113line_errors += 1114f.write('''</tr>\n''')115116f.write('''</table>\n''')117118# write summary119f.write(120'''<h2>Summary</h2>121<p>Processed %u logs<br/>122%u errors from %u logs<br/>123<hr>124<p>Tolerance Euler: %.3f degrees<br/>125Tolerance Position: %.3f meters<br/>126Tolerance Velocity: %.3f meters/second127''' % (line_count, error_count, line_errors,128opts.tolerance_euler,129opts.tolerance_pos,130opts.tolerance_vel))131132# add trailer133f.write(134'''135</body>136</html>137''')138f.close()139infile.close()140141def check_logs():142'''run log checking'''143log_list = get_log_list()144145# remove old results file146try:147os.unlink("replay_results.txt")148except Exception as ex:149print(ex)150151for logfile in log_list:152run_replay(logfile)153154create_html_results()155156def create_checked_logs():157'''create a set of CHEK logs'''158import glob, sys159if os.path.isfile(opts.logdir):160full_file_list = [opts.logdir]161else:162pattern = os.path.join(opts.logdir, "*.bin")163full_file_list = glob.glob(pattern)164file_list = []165for f in full_file_list:166if not f.endswith("-checked.bin"):167file_list.append(f)168if len(file_list) == 0:169print("No files to process")170sys.exit(1)171for f in file_list:172print("Processing %s" % f)173log_list_current = set(glob.glob("logs/*.BIN"))174cmd = "./Replay.elf -- --check-generate %s" % f175run_cmd(cmd, checkfail=True)176log_list_after = set(glob.glob("logs/*.BIN"))177changed = log_list_after.difference(log_list_current)178if len(changed) != 1:179print("Failed to generate log for %s" % f)180sys.exit(1)181outlog = list(changed)[0]182name, ext = os.path.splitext(f)183newname = name + '-checked.bin'184os.rename(outlog, newname)185print("Created %s" % newname)186187if opts.create_checked_logs:188create_checked_logs()189sys.exit(0)190191check_logs()192193194