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