aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2020-09-09 17:09:01 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-09 23:37:54 +0100
commit0457482e252f216618a6fccad0030fcd6c5a304f (patch)
treed524ff5d4c2ca827ac2622ab36151e002d1f8f60 /contrib
parentb88816c4c84fa4f5ad39c263f5e75b96476e9768 (diff)
downloadbitbake-0457482e252f216618a6fccad0030fcd6c5a304f.tar.gz
bitbake: Add parsing torture test
Adds a contrib/ script that repeatedly runs bitbake and interrupts parsing to try and reproduce parsing deadlocks. Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'contrib')
-rwxr-xr-xcontrib/bbparse-torture.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/contrib/bbparse-torture.py b/contrib/bbparse-torture.py
new file mode 100755
index 000000000..c25d547bb
--- /dev/null
+++ b/contrib/bbparse-torture.py
@@ -0,0 +1,89 @@
+#! /usr/bin/env python3
+#
+# Copyright (C) 2020 Joshua Watt <JPEWhacker@gmail.com>
+#
+# SPDX-License-Identifier: MIT
+
+import argparse
+import os
+import random
+import shutil
+import signal
+import subprocess
+import sys
+import time
+
+
+def try_unlink(path):
+ try:
+ os.unlink(path)
+ except:
+ pass
+
+
+def main():
+ def cleanup():
+ shutil.rmtree("tmp/cache", ignore_errors=True)
+ try_unlink("bitbake-cookerdaemon.log")
+ try_unlink("bitbake.sock")
+ try_unlink("bitbake.lock")
+
+ parser = argparse.ArgumentParser(
+ description="Bitbake parser torture test",
+ epilog="""
+ A torture test for bitbake's parser. Repeatedly interrupts parsing until
+ bitbake decides to deadlock.
+ """,
+ )
+
+ args = parser.parse_args()
+
+ if not "BUILDDIR" in os.environ:
+ print(
+ "'BUILDDIR' not found in the environment. Did you initialize the build environment?"
+ )
+ return 1
+
+ os.chdir(os.environ["BUILDDIR"])
+
+ run_num = 0
+ while True:
+ if run_num % 100 == 0:
+ print("Calibrating wait time...")
+ cleanup()
+
+ start_time = time.monotonic()
+ r = subprocess.run(["bitbake", "-p"])
+ max_wait_time = time.monotonic() - start_time
+
+ if r.returncode != 0:
+ print("Calibration run exited with %d" % r.returncode)
+ return 1
+
+ print("Maximum wait time is %f seconds" % max_wait_time)
+
+ run_num += 1
+ wait_time = random.random() * max_wait_time
+
+ print("Run #%d" % run_num)
+ print("Will sleep for %f seconds" % wait_time)
+
+ cleanup()
+ with subprocess.Popen(["bitbake", "-p"]) as proc:
+ time.sleep(wait_time)
+ proc.send_signal(signal.SIGINT)
+ try:
+ proc.wait(45)
+ except subprocess.TimeoutExpired:
+ print("Run #%d: Waited too long. Possible deadlock!" % run_num)
+ proc.wait()
+ return 1
+
+ if proc.returncode == 0:
+ print("Exited successfully. Timeout too long?")
+ else:
+ print("Exited with %d" % proc.returncode)
+
+
+if __name__ == "__main__":
+ sys.exit(main())