Fix up regression tester

* Clean up to support pydoc
* Support -h
* Make it actually work
* Improve docstrings
* Add copyright

Change-Id: I977df71e8213e39e9eebf9cc56b2dd7625959870
This commit is contained in:
Joe Gordon
2013-04-15 18:00:24 -07:00
parent a01f907cec
commit 49c58da95b
+85 -57
View File
@@ -1,81 +1,109 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Tool for checking if patch contains a regression test. """Tool for checking if patch contains a regression test.
Pass in gerrit review number as parameter, tool will download branch and run By default runs against current patch but can be set to use any gerrit review
modified tests without bug fix. as specified by change number (uses 'git review -d').
Idea: take tests from patch to check, and run against code from previous patch.
If new tests pass, then no regression test, if new tests fails against old code
then either
* new tests depend on new code and cannot confirm regression test is valid
(false positive)
* new tests detects the bug being fixed (detect valid regression test)
Due to the risk of false positives, the results from this need some human
interpretation.
""" """
import optparse
import string import string
import subprocess import subprocess
import sys import sys
gerrit_number = None
#TODO(jogo) use proper optParser
if len(sys.argv) == 2:
gerrit_number = sys.argv[1]
else:
gerrit_number = None
print ("no gerrit review number specified, running on latest commit"
"on current branch.")
def run(cmd, fail_ok=False): def run(cmd, fail_ok=False):
print "running: %s" % cmd print "running: %s" % cmd
try: obj = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
rval = subprocess.check_output(cmd, shell=True) shell=True)
except subprocess.CalledProcessError: obj.wait()
if not fail_ok: if obj.returncode != 0 and not fail_ok:
print "The command above terminated with an error." print "The above command terminated with an error."
sys.exit(1) sys.exit(obj.returncode)
pass return obj.stdout.read()
return rval
test_works = False def main():
usage = """
Tool for checking if a patch includes a regression test.
if gerrit_number: Usage: %prog [options]"""
original_branch = run("git rev-parse --abbrev-ref HEAD") parser = optparse.OptionParser(usage)
run("git review -d %s" % gerrit_number) parser.add_option("-r", "--review", dest="review",
help="gerrit review number to test")
(options, args) = parser.parse_args()
if options.review:
original_branch = run("git rev-parse --abbrev-ref HEAD")
run("git review -d %s" % options.review)
else:
print ("no gerrit review number specified, running on latest commit"
"on current branch.")
# run new tests with old code
run("git checkout HEAD^ nova")
run("git checkout HEAD nova/tests")
# identify which tests have changed
tests = run("git whatchanged --format=oneline -1 | grep \"nova/tests\" "
"| cut -f2").split()
test_list = []
for test in tests:
test_list.append(string.replace(test[0:-3], '/', '.'))
if test_list == []:
test_works = False test_works = False
expect_failure = ""
else:
# run new tests, expect them to fail
expect_failure = run(("tox -epy27 %s 2>&1" % string.join(test_list)),
fail_ok=True)
if "FAILED (id=" in expect_failure:
test_works = True
# cleanup # run new tests with old code
run("git checkout HEAD nova") run("git checkout HEAD^ nova")
if gerrit_number: run("git checkout HEAD nova/tests")
new_branch = run("git status | head -1 | cut -d ' ' -f 4")
run("git checkout %s" % original_branch)
run("git branch -D %s" % new_branch)
# identify which tests have changed
tests = run("git whatchanged --format=oneline -1 | grep \"nova/tests\" "
"| cut -f2").split()
test_list = []
for test in tests:
test_list.append(string.replace(test[0:-3], '/', '.'))
if test_list == []:
test_works = False
expect_failure = ""
else:
# run new tests, expect them to fail
expect_failure = run(("tox -epy27 %s 2>&1" % string.join(test_list)),
fail_ok=True)
if "FAILED (id=" in expect_failure:
test_works = True
# cleanup
run("git checkout HEAD nova")
if options.review:
new_branch = run("git status | head -1 | cut -d ' ' -f 4")
run("git checkout %s" % original_branch)
run("git branch -D %s" % new_branch)
if test_works:
print expect_failure print expect_failure
print "" print ""
print "*******************************" print "*******************************"
print "FOUND a regression test" if test_works:
else: print "FOUND a regression test"
print expect_failure else:
print "" print "NO regression test"
print "*******************************" sys.exit(1)
print "NO regression test"
sys.exit(1)
if __name__ == "__main__":
main()