1#!/usr/bin/python
2
3"""
4Copyright 2014 Google Inc.
5
6Use of this source code is governed by a BSD-style license that can be
7found in the LICENSE file.
8
9A wrapper around the standard Python unittest library, adding features we need
10for various unittests within this directory.
11"""
12
13import errno
14import os
15import shutil
16import sys
17import unittest
18
19# Set the PYTHONPATH to include the tools directory.
20sys.path.append(
21    os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
22import find_run_binary
23
24
25class TestCase(unittest.TestCase):
26
27  def shortDescription(self):
28    """Tell unittest framework to not print docstrings for test cases."""
29    return None
30
31  def create_empty_dir(self, path):
32    """Creates an empty directory at path and returns path.
33
34    Args:
35      path: path on local disk
36    """
37    shutil.rmtree(path=path, ignore_errors=True)
38    try:
39      os.makedirs(path)
40    except OSError as exc:
41      if exc.errno != errno.EEXIST:
42        raise
43    return path
44
45  def run_command(self, args):
46    """Runs a program from the command line and returns stdout.
47
48    Args:
49      args: Command line to run, as a list of string parameters. args[0] is the
50            binary to run.
51
52    Returns:
53      stdout from the program, as a single string.
54
55    Raises:
56      Exception: the program exited with a nonzero return code.
57    """
58    return find_run_binary.run_command(args)
59
60  def find_path_to_program(self, program):
61    """Returns path to an existing program binary.
62
63    Args:
64      program: Basename of the program to find (e.g., 'render_pictures').
65
66    Returns:
67      Absolute path to the program binary, as a string.
68
69    Raises:
70      Exception: unable to find the program binary.
71    """
72    return find_run_binary.find_path_to_program(program)
73
74
75def main(test_case_class):
76  """Run the unit tests within the given class.
77
78  Raises an Exception if any of those tests fail (in case we are running in the
79  context of run_all.py, which depends on that Exception to signal failures).
80
81  TODO(epoger): Make all of our unit tests use the Python unittest framework,
82  so we can leverage its ability to run *all* the tests and report failures at
83  the end.
84  """
85  suite = unittest.TestLoader().loadTestsFromTestCase(test_case_class)
86  results = unittest.TextTestRunner(verbosity=2).run(suite)
87  if not results.wasSuccessful():
88    raise Exception('failed unittest %s' % test_case_class)
89