lit_test.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. """Runs `lit` for testing."""
  2. __copyright__ = """
  3. Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  4. Exceptions. See /LICENSE for license information.
  5. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. """
  7. import argparse
  8. import os
  9. import subprocess
  10. _PASSTHROUGH_FLAGS = ["filter", "filter-out"]
  11. def _parse_args():
  12. """Parses command line arguments, returning the result."""
  13. arg_parser = argparse.ArgumentParser(description=__doc__)
  14. arg_parser.add_argument(
  15. "test_dir", help="The directory containing tests to run."
  16. )
  17. arg_parser.add_argument(
  18. "lit_args", nargs="*", help="Arguments to pass through to lit."
  19. )
  20. arg_parser.add_argument(
  21. "--tool", action="append", help="A tool to add to the PATH."
  22. )
  23. return arg_parser.parse_args()
  24. def _normalize(relative_base, target):
  25. """Given a target, normalizes it to a relative path."""
  26. assert target
  27. if target.startswith(":"):
  28. # Local target; :foo -> my/dir/foo
  29. return os.path.join(relative_base, target[1:])
  30. elif target[0].isalpha():
  31. # Local target; foo -> my/dir/foo
  32. return os.path.join(relative_base, target)
  33. if ":" in target:
  34. # Specified target; //foo:bar -> //foo/bar
  35. target = target.replace(":", "/")
  36. else:
  37. # Default target; //foo -> //foo/foo
  38. target = os.path.join(target, os.path.basename(target))
  39. if target.startswith("@"):
  40. return os.path.join("external/", target[1:])
  41. elif target.startswith("//"):
  42. return target[2:]
  43. else:
  44. raise ValueError("Unhandled target path: %s" % target)
  45. def main():
  46. parsed_args = _parse_args()
  47. # A symlink directory is added to the PATH so that commands like `lit` and
  48. # `not` can use the versions in the path.
  49. symlink_dir = os.environ["TEST_TMPDIR"]
  50. # Create symlinks to all the tools.
  51. bin_dir = os.getcwd()
  52. relative_base = os.path.dirname(_normalize("", os.environ["TEST_TARGET"]))
  53. for tool in parsed_args.tool:
  54. tool_path = _normalize(relative_base, tool)
  55. symlink_loc = os.path.join(symlink_dir, os.path.basename(tool_path))
  56. symlinked_file = os.path.join(bin_dir, tool_path)
  57. if not os.path.exists(symlinked_file):
  58. raise ValueError("Missing file: %s" % symlinked_file)
  59. os.symlink(symlinked_file, symlink_loc)
  60. # Figure out the actual path for the test_dir.
  61. test_dir = os.path.join(
  62. bin_dir, _normalize(relative_base, parsed_args.test_dir)
  63. )
  64. args = [
  65. os.path.join(symlink_dir, "lit"),
  66. "--path=%s" % symlink_dir,
  67. test_dir,
  68. "-sv",
  69. ]
  70. # Run lit.
  71. p = subprocess.run(args=args + parsed_args.lit_args)
  72. # Do this instead of check_call to hide stack traces.
  73. if p.returncode != 0:
  74. exit("lit failed, exit code %d" % p.returncode)
  75. if __name__ == "__main__":
  76. exit(main())