run_checks.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # This file runs some basic checks to verify kunit works.
  5. # It is only of interest if you're making changes to KUnit itself.
  6. #
  7. # Copyright (C) 2021, Google LLC.
  8. # Author: Daniel Latypov <[email protected]>
  9. from concurrent import futures
  10. import datetime
  11. import os
  12. import shutil
  13. import subprocess
  14. import sys
  15. import textwrap
  16. from typing import Dict, List, Sequence
  17. ABS_TOOL_PATH = os.path.abspath(os.path.dirname(__file__))
  18. TIMEOUT = datetime.timedelta(minutes=5).total_seconds()
  19. commands: Dict[str, Sequence[str]] = {
  20. 'kunit_tool_test.py': ['./kunit_tool_test.py'],
  21. 'kunit smoke test': ['./kunit.py', 'run', '--kunitconfig=lib/kunit', '--build_dir=kunit_run_checks'],
  22. 'pytype': ['/bin/sh', '-c', 'pytype *.py'],
  23. 'mypy': ['/bin/sh', '-c', 'mypy *.py'],
  24. }
  25. # The user might not have mypy or pytype installed, skip them if so.
  26. # Note: you can install both via `$ pip install mypy pytype`
  27. necessary_deps : Dict[str, str] = {
  28. 'pytype': 'pytype',
  29. 'mypy': 'mypy',
  30. }
  31. def main(argv: Sequence[str]) -> None:
  32. if argv:
  33. raise RuntimeError('This script takes no arguments')
  34. future_to_name: Dict[futures.Future, str] = {}
  35. executor = futures.ThreadPoolExecutor(max_workers=len(commands))
  36. for name, argv in commands.items():
  37. if name in necessary_deps and shutil.which(necessary_deps[name]) is None:
  38. print(f'{name}: SKIPPED, {necessary_deps[name]} not in $PATH')
  39. continue
  40. f = executor.submit(run_cmd, argv)
  41. future_to_name[f] = name
  42. has_failures = False
  43. print(f'Waiting on {len(future_to_name)} checks ({", ".join(future_to_name.values())})...')
  44. for f in futures.as_completed(future_to_name.keys()):
  45. name = future_to_name[f]
  46. ex = f.exception()
  47. if not ex:
  48. print(f'{name}: PASSED')
  49. continue
  50. has_failures = True
  51. if isinstance(ex, subprocess.TimeoutExpired):
  52. print(f'{name}: TIMED OUT')
  53. elif isinstance(ex, subprocess.CalledProcessError):
  54. print(f'{name}: FAILED')
  55. else:
  56. print(f'{name}: unexpected exception: {ex}')
  57. continue
  58. output = ex.output
  59. if output:
  60. print(textwrap.indent(output.decode(), '> '))
  61. executor.shutdown()
  62. if has_failures:
  63. sys.exit(1)
  64. def run_cmd(argv: Sequence[str]):
  65. subprocess.check_output(argv, stderr=subprocess.STDOUT, cwd=ABS_TOOL_PATH, timeout=TIMEOUT)
  66. if __name__ == '__main__':
  67. main(sys.argv[1:])