summaryrefslogtreecommitdiffstats
path: root/Tools/Scripts/webkitpy/test/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/test/main.py')
-rw-r--r--Tools/Scripts/webkitpy/test/main.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/Tools/Scripts/webkitpy/test/main.py b/Tools/Scripts/webkitpy/test/main.py
new file mode 100644
index 0000000..1038d82
--- /dev/null
+++ b/Tools/Scripts/webkitpy/test/main.py
@@ -0,0 +1,140 @@
+# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains the entry method for test-webkitpy."""
+
+import logging
+import os
+import sys
+import unittest
+
+import webkitpy
+
+
+_log = logging.getLogger(__name__)
+
+
+class Tester(object):
+
+ """Discovers and runs webkitpy unit tests."""
+
+ def _find_unittest_files(self, webkitpy_dir):
+ """Return a list of paths to all unit-test files."""
+ unittest_paths = [] # Return value.
+
+ for dir_path, dir_names, file_names in os.walk(webkitpy_dir):
+ for file_name in file_names:
+ if not file_name.endswith("_unittest.py"):
+ continue
+ unittest_path = os.path.join(dir_path, file_name)
+ unittest_paths.append(unittest_path)
+
+ return unittest_paths
+
+ def _modules_from_paths(self, package_root, paths):
+ """Return a list of fully-qualified module names given paths."""
+ package_path = os.path.abspath(package_root)
+ root_package_name = os.path.split(package_path)[1] # Equals "webkitpy".
+
+ prefix_length = len(package_path)
+
+ modules = []
+ for path in paths:
+ path = os.path.abspath(path)
+ # This gives us, for example: /common/config/ports_unittest.py
+ rel_path = path[prefix_length:]
+ # This gives us, for example: /common/config/ports_unittest
+ rel_path = os.path.splitext(rel_path)[0]
+
+ parts = []
+ while True:
+ (rel_path, tail) = os.path.split(rel_path)
+ if not tail:
+ break
+ parts.insert(0, tail)
+ # We now have, for example: common.config.ports_unittest
+ # FIXME: This is all a hack around the fact that we always prefix webkitpy includes with "webkitpy."
+ parts.insert(0, root_package_name) # Put "webkitpy" at the beginning.
+ module = ".".join(parts)
+ modules.append(module)
+
+ return modules
+
+ def run_tests(self, sys_argv, external_package_paths=None):
+ """Run the unit tests in all *_unittest.py modules in webkitpy.
+
+ This method excludes "webkitpy.common.checkout.scm_unittest" unless
+ the --all option is the second element of sys_argv.
+
+ Args:
+ sys_argv: A reference to sys.argv.
+
+ """
+ if external_package_paths is None:
+ external_package_paths = []
+ else:
+ # FIXME: We should consider moving webkitpy off of using "webkitpy." to prefix
+ # all includes. If we did that, then this would use path instead of dirname(path).
+ # QueueStatusServer.__init__ has a sys.path import hack due to this code.
+ sys.path.extend(set(os.path.dirname(path) for path in external_package_paths))
+
+ if len(sys_argv) > 1 and not sys_argv[-1].startswith("-"):
+ # Then explicit modules or test names were provided, which
+ # the unittest module is equipped to handle.
+ unittest.main(argv=sys_argv, module=None)
+ # No need to return since unitttest.main() exits.
+
+ # Otherwise, auto-detect all unit tests.
+
+ # FIXME: This should be combined with the external_package_paths code above.
+ webkitpy_dir = os.path.dirname(webkitpy.__file__)
+
+ modules = []
+ for path in [webkitpy_dir] + external_package_paths:
+ modules.extend(self._modules_from_paths(path, self._find_unittest_files(path)))
+ modules.sort()
+
+ # This is a sanity check to ensure that the unit-test discovery
+ # methods are working.
+ if len(modules) < 1:
+ raise Exception("No unit-test modules found.")
+
+ for module in modules:
+ _log.debug("Found: %s" % module)
+
+ # FIXME: This is a hack, but I'm tired of commenting out the test.
+ # See https://bugs.webkit.org/show_bug.cgi?id=31818
+ if len(sys_argv) > 1 and sys.argv[1] == "--all":
+ sys.argv.remove("--all")
+ else:
+ excluded_module = "webkitpy.common.checkout.scm_unittest"
+ _log.info("Excluding: %s (use --all to include)" % excluded_module)
+ modules.remove(excluded_module)
+
+ sys_argv.extend(modules)
+
+ # We pass None for the module because we do not want the unittest
+ # module to resolve module names relative to a given module.
+ # (This would require importing all of the unittest modules from
+ # this module.) See the loadTestsFromName() method of the
+ # unittest.TestLoader class for more details on this parameter.
+ unittest.main(argv=sys_argv, module=None)