0

# This is a combination of 7 commits.

# This is the 1st commit message:

testRender.py Python3 refactor

# The commit message #2 will be skipped:

# Popen -> subprocess.run

# The commit message #3 will be skipped:

# split subprocess args

# The commit message #4 will be skipped:

# map -> list comprehension

# The commit message #5 will be skipped:

# optparse->argparse

# The commit message #6 will be skipped:

# factor out CLI parsing from main logic

# The commit message #7 will be skipped:

# fix backwards verbose/quiet behaviour
This commit is contained in:
Ben Steadman
2019-03-28 18:54:37 +00:00
parent 36f55ea7b4
commit dd11cdd03b

View File

@@ -1,43 +1,47 @@
#!/usr/bin/python
#!/usr/bin/env python3
"Test Render Script"
import os, shutil, tempfile, time, sys, math, re
from subprocess import Popen, PIPE, STDOUT, CalledProcessError
from optparse import OptionParser
import argparse
import math
import os
import re
import shutil
import sys
import tempfile
import time
from shlex import split
from subprocess import PIPE, STDOUT, CalledProcessError, run
overviewer_scripts = ['./overviewer.py', './gmap.py']
def check_call(*args, **kwargs):
quiet = False
if "quiet" in kwargs.keys():
quiet = kwargs["quiet"]
del kwargs["quiet"]
if quiet:
kwargs['stdout'] = PIPE
kwargs['stderr'] = STDOUT
p = Popen(*args, **kwargs)
output = ""
if quiet:
while p.poll() == None:
output += p.communicate()[0]
returncode = p.wait()
if returncode:
if quiet:
print output
raise CalledProcessError(returncode, args)
return returncode
def check_output(*args, **kwargs):
kwargs['stdout'] = PIPE
# will hang for HUGE output... you were warned
p = Popen(*args, **kwargs)
returncode = p.wait()
if returncode:
raise CalledProcessError(returncode, args)
return p.communicate()[0]
def check_call(args, verbose=False):
try:
return run(
args,
check=True,
stdout=None if verbose else PIPE,
stderr=None if verbose else STDOUT,
universal_newlines=True,
)
except CalledProcessError as e:
if verbose:
print(e.output)
raise e
def clean_render(overviewerargs, quiet):
def check_output(args):
p = run(
args,
check=True,
stdout=PIPE,
universal_newlines=True
)
return p.stdout
def clean_render(overviewerargs, verbose=False):
tempdir = tempfile.mkdtemp('mc-overviewer-test')
overviewer_script = None
for script in overviewer_scripts:
@@ -47,115 +51,121 @@ def clean_render(overviewerargs, quiet):
if overviewer_script is None:
sys.stderr.write("could not find main overviewer script\n")
sys.exit(1)
try:
# check_call raises CalledProcessError when overviewer.py exits badly
check_call([sys.executable, 'setup.py', 'clean', 'build'], quiet=quiet)
check_call([sys.executable] + split("setup.py clean build"), verbose=verbose)
try:
check_call([sys.executable, overviewer_script, '-d'] + overviewerargs, quiet=quiet)
check_call([sys.executable, overviewer_script, '-d'] + overviewerargs, verbose=verbose)
except CalledProcessError:
pass
starttime = time.time()
check_call([sys.executable, overviewer_script,] + overviewerargs + [tempdir,], quiet=quiet)
check_call([sys.executable, overviewer_script] +
overviewerargs + [tempdir, ], verbose=verbose)
endtime = time.time()
return endtime - starttime
finally:
shutil.rmtree(tempdir, True)
def get_stats(timelist):
stats = {}
stats['count'] = len(timelist)
stats['minimum'] = min(timelist)
stats['maximum'] = max(timelist)
stats['average'] = sum(timelist) / float(len(timelist))
meandiff = map(lambda x: (x - stats['average'])**2, timelist)
stats['standard deviation'] = math.sqrt(sum(meandiff) / float(len(meandiff)))
return stats
average = sum(timelist) / float(len(timelist))
meandiff = [(x - stats["average"]) ** 2 for x in timelist]
sd = math.sqrt(sum(meandiff) / len(meandiff))
return {
"count": len(timelist),
"minimum": min(timelist),
"maximum": max(timelist),
"average": average,
"standard deviation": sd
}
commitre = re.compile('^commit ([a-z0-9]{40})$', re.MULTILINE)
branchre = re.compile('^\\* (.+)$', re.MULTILINE)
def get_current_commit():
gittext = check_output(['git', 'branch'])
gittext = check_output(split('git branch'))
match = branchre.search(gittext)
if match and not ("no branch" in match.group(1)):
return match.group(1)
gittext = check_output(['git', 'show', 'HEAD'])
gittext = check_output(split('git show HEAD'))
match = commitre.match(gittext)
if match == None:
return None
return match.group(1)
def get_commits(gitrange):
gittext = check_output(['git', 'log', '--raw', '--reverse', gitrange])
gittext = check_output(split('git log --raw --reverse') + [gitrange, ])
for match in commitre.finditer(gittext):
yield match.group(1)
def set_commit(commit):
check_call(['git', 'checkout', commit], quiet=True)
check_call(split('git checkout') + [commit, ])
parser = OptionParser(usage="usage: %prog [options] -- [overviewer options/world]")
parser.add_option("-n", "--number", metavar="N",
action="store", type="int", dest="number", default=3,
help="number of renders per commit [default: 3]")
parser.add_option("-c", "--commits", metavar="RANGE",
action="append", type="string", dest="commits", default=[],
help="the commit (or range of commits) to test [default: current]")
parser.add_option("-v", "--verbose",
action="store_false", dest="quiet", default=True,
help="don't suppress overviewer output")
parser.add_option("-k", "--keep-going",
action="store_false", dest="fatal_errors", default=True,
help="don't stop testing when Overviewer croaks")
parser.add_option("-l", "--log", dest="log", default="", metavar="FILE",
help="log all test results to a file")
(options, args) = parser.parse_args()
def main(args):
commits = []
for commit in args.commits:
if '..' in commit:
commits = get_commits(commit)
else:
commits.append(commit)
if not commits:
commits = [get_current_commit(), ]
if len(args) == 0:
parser.print_help()
sys.exit(0)
log = None
if args.log:
log = args.log
commits = []
for commit in options.commits:
if '..' in commit:
commits = get_commits(commit)
else:
commits.append(commit)
if not commits:
commits = [get_current_commit(),]
reset_commit = get_current_commit()
try:
for commit in commits:
print("testing commit", commit)
set_commit(commit)
timelist = []
print(" -- "),
try:
for i in range(args.number):
sys.stdout.write(str(i + 1) + " ")
sys.stdout.flush()
timelist.append(clean_render(args.overviewer_args, verbose=args.verbose))
print("... done")
stats = get_stats(timelist)
print(stats)
if log:
log.write("%s %s\n" % (commit, repr(stats)))
except CalledProcessError as e:
if args.fatal_errors:
print(e)
print("Overviewer croaked, exiting...")
print("(to avoid this, use --keep-going)")
sys.exit(1)
finally:
set_commit(reset_commit)
if log:
log.close()
log = None
if options.log != "":
log = open(options.log, "w")
reset_commit = get_current_commit()
try:
for commit in commits:
print "testing commit", commit
set_commit(commit)
timelist = []
print " -- ",
try:
for i in range(options.number):
sys.stdout.write(str(i+1)+" ")
sys.stdout.flush()
timelist.append(clean_render(args, options.quiet))
print "... done"
stats = get_stats(timelist)
print stats
if log:
log.write("%s %s\n" % (commit, repr(stats)))
except CalledProcessError, e:
if options.fatal_errors:
print
print "Overviewer croaked, exiting..."
print "(to avoid this, use --keep-going)"
sys.exit(1)
finally:
set_commit(reset_commit)
if log:
log.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("overviewer_args", metavar="[overviewer options/world]", nargs="+")
parser.add_argument("-n", "--option", metavar="N", type=int, action="store",
dest="number", default=3, help="number of renders per commit [default: 3]")
parser.add_argument("-c", "--commits", metavar="RANGE",
action="append", type=str, dest="commits", default=[],
help="the commit (or range of commits) to test [default: current]")
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", default=False,
help="don't suppress overviewer output")
parser.add_argument("-k", "--keep-going",
action="store_false", dest="fatal_errors", default=True,
help="don't stop testing when Overviewer croaks")
parser.add_argument("-l", "--log", dest="log", type=argparse.FileType('w'), metavar="FILE",
help="log all test results to a file")
args = parser.parse_args()
main(args)