bbparse-torture.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #! /usr/bin/env python3
  2. #
  3. # Copyright (C) 2020 Joshua Watt <JPEWhacker@gmail.com>
  4. #
  5. # SPDX-License-Identifier: MIT
  6. import argparse
  7. import os
  8. import random
  9. import shutil
  10. import signal
  11. import subprocess
  12. import sys
  13. import time
  14. def try_unlink(path):
  15. try:
  16. os.unlink(path)
  17. except:
  18. pass
  19. def main():
  20. def cleanup():
  21. shutil.rmtree("tmp/cache", ignore_errors=True)
  22. try_unlink("bitbake-cookerdaemon.log")
  23. try_unlink("bitbake.sock")
  24. try_unlink("bitbake.lock")
  25. parser = argparse.ArgumentParser(
  26. description="Bitbake parser torture test",
  27. epilog="""
  28. A torture test for bitbake's parser. Repeatedly interrupts parsing until
  29. bitbake decides to deadlock.
  30. """,
  31. )
  32. args = parser.parse_args()
  33. if not "BUILDDIR" in os.environ:
  34. print(
  35. "'BUILDDIR' not found in the environment. Did you initialize the build environment?"
  36. )
  37. return 1
  38. os.chdir(os.environ["BUILDDIR"])
  39. run_num = 0
  40. while True:
  41. if run_num % 100 == 0:
  42. print("Calibrating wait time...")
  43. cleanup()
  44. start_time = time.monotonic()
  45. r = subprocess.run(["bitbake", "-p"])
  46. max_wait_time = time.monotonic() - start_time
  47. if r.returncode != 0:
  48. print("Calibration run exited with %d" % r.returncode)
  49. return 1
  50. print("Maximum wait time is %f seconds" % max_wait_time)
  51. run_num += 1
  52. wait_time = random.random() * max_wait_time
  53. print("Run #%d" % run_num)
  54. print("Will sleep for %f seconds" % wait_time)
  55. cleanup()
  56. with subprocess.Popen(["bitbake", "-p"]) as proc:
  57. time.sleep(wait_time)
  58. proc.send_signal(signal.SIGINT)
  59. try:
  60. proc.wait(45)
  61. except subprocess.TimeoutExpired:
  62. print("Run #%d: Waited too long. Possible deadlock!" % run_num)
  63. proc.wait()
  64. return 1
  65. if proc.returncode == 0:
  66. print("Exited successfully. Timeout too long?")
  67. else:
  68. print("Exited with %d" % proc.returncode)
  69. if __name__ == "__main__":
  70. sys.exit(main())