test: Add --sit argument to check-* scripts

Cockpit has this. It's very useful for debugging a failing test locally.
This commit is contained in:
Lars Karlitski 2019-05-24 09:47:01 +02:00 committed by Martin Pitt
parent 29cf2c4e8c
commit 5dda214c39
2 changed files with 33 additions and 4 deletions

View File

@ -42,8 +42,9 @@ After building a test image, run
$ ./test/check-cli [TESTNAME] $ ./test/check-cli [TESTNAME]
or any of the other `check-*` scripts. Right after the VM is started, these or any of the other `check-*` scripts. To debug a test failure, pass `--sit`.
scripts print an `ssh` line to connect to it. This will keep the test machine running after the first failure and print an
ssh line to connect to it.
Run `make vm` after changing tests or lorax source to recreate the test Run `make vm` after changing tests or lorax source to recreate the test
machine. It is usually not necessary to reset the VM. machine. It is usually not necessary to reset the VM.

View File

@ -11,8 +11,21 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "../bots/machine"))
import testvm # pylint: disable=import-error import testvm # pylint: disable=import-error
def print_exception(etype, value, tb):
import traceback
# only include relevant lines
limit = 0
while tb and '__unittest' in tb.tb_frame.f_globals:
limit += 1
tb = tb.tb_next
traceback.print_exception(etype, value, tb, limit=limit)
class ComposerTestCase(unittest.TestCase): class ComposerTestCase(unittest.TestCase):
image = testvm.DEFAULT_IMAGE image = testvm.DEFAULT_IMAGE
sit = False
def setUp(self): def setUp(self):
network = testvm.VirtNetwork(0) network = testvm.VirtNetwork(0)
@ -42,6 +55,18 @@ class ComposerTestCase(unittest.TestCase):
self.assertEqual(r.returncode, 0) self.assertEqual(r.returncode, 0)
def tearDown(self): def tearDown(self):
# Peek into internal data structure, because there's no way to get the
# TestResult at this point. `errors` is a list of tuples (method, error)
errors = filter(None, [ e[1] for e in self._outcome.errors ])
if errors and self.sit:
for e in errors:
print_exception(*e)
print()
print(" ".join(self.ssh_command))
input("Press RETURN to continue...")
self.machine.stop() self.machine.stop()
def execute(self, command, **args): def execute(self, command, **args):
@ -59,15 +84,18 @@ class ComposerTestCase(unittest.TestCase):
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("tests", nargs="*", help="List of tests modules, classes, and methods") parser.add_argument("tests", nargs="*", help="List of tests modules, classes, and methods")
parser.add_argument("-s", "--sit", action="store_true", help="Halt test execution (but keep VM running) when a test fails")
args = parser.parse_args() args = parser.parse_args()
module = __import__("__main__") ComposerTestCase.sit = args.sit
module = __import__("__main__")
if args.tests: if args.tests:
tests = unittest.defaultTestLoader.loadTestsFromNames(args.tests, module) tests = unittest.defaultTestLoader.loadTestsFromNames(args.tests, module)
else: else:
tests = unittest.defaultTestLoader.loadTestsFromModule(module) tests = unittest.defaultTestLoader.loadTestsFromModule(module)
runner = unittest.TextTestRunner(verbosity=2) runner = unittest.TextTestRunner(verbosity=2, failfast=args.sit)
result = runner.run(tests) result = runner.run(tests)
sys.exit(not result.wasSuccessful()) sys.exit(not result.wasSuccessful())