WebKitTools/Scripts/webkitpy/test/main.py
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
       
     2 #
       
     3 # Redistribution and use in source and binary forms, with or without
       
     4 # modification, are permitted provided that the following conditions
       
     5 # are met:
       
     6 # 1.  Redistributions of source code must retain the above copyright
       
     7 #     notice, this list of conditions and the following disclaimer.
       
     8 # 2.  Redistributions in binary form must reproduce the above copyright
       
     9 #     notice, this list of conditions and the following disclaimer in the
       
    10 #     documentation and/or other materials provided with the distribution.
       
    11 #
       
    12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
       
    13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
       
    16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
       
    18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
       
    19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
       
    20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    22 
       
    23 """Contains the entry method for test-webkitpy."""
       
    24 
       
    25 import logging
       
    26 import os
       
    27 import sys
       
    28 import unittest
       
    29 
       
    30 import webkitpy
       
    31 
       
    32 
       
    33 _log = logging.getLogger(__name__)
       
    34 
       
    35 
       
    36 class Tester(object):
       
    37 
       
    38     """Discovers and runs webkitpy unit tests."""
       
    39 
       
    40     def _find_unittest_files(self, webkitpy_dir):
       
    41         """Return a list of paths to all unit-test files."""
       
    42         unittest_paths = []  # Return value.
       
    43 
       
    44         for dir_path, dir_names, file_names in os.walk(webkitpy_dir):
       
    45             for file_name in file_names:
       
    46                 if not file_name.endswith("_unittest.py"):
       
    47                     continue
       
    48                 unittest_path = os.path.join(dir_path, file_name)
       
    49                 unittest_paths.append(unittest_path)
       
    50 
       
    51         return unittest_paths
       
    52 
       
    53     def _modules_from_paths(self, webkitpy_dir, paths):
       
    54         """Return a list of fully-qualified module names given paths."""
       
    55         webkitpy_dir = os.path.abspath(webkitpy_dir)
       
    56         webkitpy_name = os.path.split(webkitpy_dir)[1]  # Equals "webkitpy".
       
    57 
       
    58         prefix_length = len(webkitpy_dir)
       
    59 
       
    60         modules = []
       
    61         for path in paths:
       
    62             path = os.path.abspath(path)
       
    63             # This gives us, for example: /common/config/ports_unittest.py
       
    64             rel_path = path[prefix_length:]
       
    65             # This gives us, for example: /common/config/ports_unittest
       
    66             rel_path = os.path.splitext(rel_path)[0]
       
    67 
       
    68             parts = []
       
    69             while True:
       
    70                 (rel_path, tail) = os.path.split(rel_path)
       
    71                 if not tail:
       
    72                     break
       
    73                 parts.insert(0, tail)
       
    74             # We now have, for example: common.config.ports_unittest
       
    75             parts.insert(0, webkitpy_name)  # Put "webkitpy" at the beginning.
       
    76             module = ".".join(parts)
       
    77             modules.append(module)
       
    78 
       
    79         return modules
       
    80 
       
    81     def run_tests(self, sys_argv):
       
    82         """Run the unit tests in all *_unittest.py modules in webkitpy.
       
    83 
       
    84         This method excludes "webkitpy.common.checkout.scm_unittest" unless
       
    85         the --all option is the second element of sys_argv.
       
    86 
       
    87         Args:
       
    88           sys_argv: A reference to sys.argv.
       
    89 
       
    90         """
       
    91         if len(sys_argv) > 1 and not sys_argv[-1].startswith("-"):
       
    92             # Then explicit modules or test names were provided, which
       
    93             # the unittest module is equipped to handle.
       
    94             unittest.main(argv=sys_argv, module=None)
       
    95             # No need to return since unitttest.main() exits.
       
    96 
       
    97         # Otherwise, auto-detect all unit tests.
       
    98 
       
    99         webkitpy_dir = os.path.dirname(webkitpy.__file__)
       
   100         unittest_paths = self._find_unittest_files(webkitpy_dir)
       
   101 
       
   102         modules = self._modules_from_paths(webkitpy_dir, unittest_paths)
       
   103         modules.sort()
       
   104 
       
   105         # This is a sanity check to ensure that the unit-test discovery
       
   106         # methods are working.
       
   107         if len(modules) < 1:
       
   108             raise Exception("No unit-test modules found.")
       
   109 
       
   110         for module in modules:
       
   111             _log.debug("Found: %s" % module)
       
   112 
       
   113         # FIXME: This is a hack, but I'm tired of commenting out the test.
       
   114         #        See https://bugs.webkit.org/show_bug.cgi?id=31818
       
   115         if len(sys_argv) > 1 and sys.argv[1] == "--all":
       
   116             sys.argv.remove("--all")
       
   117         else:
       
   118             excluded_module = "webkitpy.common.checkout.scm_unittest"
       
   119             _log.info("Excluding: %s (use --all to include)" % excluded_module)
       
   120             modules.remove(excluded_module)
       
   121 
       
   122         sys_argv.extend(modules)
       
   123 
       
   124         # We pass None for the module because we do not want the unittest
       
   125         # module to resolve module names relative to a given module.
       
   126         # (This would require importing all of the unittest modules from
       
   127         # this module.)  See the loadTestsFromName() method of the
       
   128         # unittest.TestLoader class for more details on this parameter.
       
   129         unittest.main(argv=sys_argv, module=None)