aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_backends_common.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-09-03 17:26:14 -0400
committerhistoria <historiavg@proton.me>2026-09-03 17:26:14 -0400
commit9dd66997033f7d306718c67745b41c16dd034865 (patch)
tree201385090c547d83cf9c60f6865b28ef1c67a927 /app/tests/test_backends_common.py
parent976f12a72ebbd330e0328991afed3524c06a35ad (diff)
downloadtts-audiobook-generator-9dd66997033f7d306718c67745b41c16dd034865.tar.gz
feat: pip install checks for bad crc errors and purges cache automatically
Diffstat (limited to 'app/tests/test_backends_common.py')
-rw-r--r--app/tests/test_backends_common.py53
1 files changed, 52 insertions, 1 deletions
diff --git a/app/tests/test_backends_common.py b/app/tests/test_backends_common.py
index 71f0c17..6e8ee1a 100644
--- a/app/tests/test_backends_common.py
+++ b/app/tests/test_backends_common.py
@@ -4,9 +4,13 @@ The streaming mode of ``run_console_subprocess`` (used by the in-TUI task
view) is exercised with a real child process: output lines are captured and
forwarded, cancellation kills the child and returns 130, an on_cancel hook
runs first, and the no-output stall watchdog kills a wedged child and
-returns 124.
+returns 124. The on_chunk console mode (raw-byte sniffing with verbatim
+terminal forwarding — pip_install's corrupted-cache detector) is exercised
+the same way.
"""
+import contextlib
+import io
import sys
import threading
import unittest
@@ -80,6 +84,53 @@ class RunConsoleSubprocessStreamingTests(unittest.TestCase):
"http://host:8080/path")
+class RunConsoleSubprocessOnChunkTests(unittest.TestCase):
+ """The on_chunk console mode: raw bytes to the hook, verbatim forward."""
+
+ def test_on_chunk_receives_raw_bytes_and_output_is_forwarded(self):
+ chunks = []
+ captured = io.StringIO()
+ with contextlib.redirect_stdout(captured):
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c",
+ "import sys; sys.stdout.write('hello\\nworld\\n')"],
+ on_chunk=chunks.append)
+ self.assertEqual(rc, 0)
+ self.assertIn(b"hello\nworld\n", b"".join(chunks))
+ # The child's output still reaches the real terminal (verbatim, so
+ # carriage-return progress bars keep animating).
+ self.assertIn("hello\nworld\n", captured.getvalue())
+
+ def test_on_chunk_path_returns_the_exit_code(self):
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c", "import sys; sys.exit(5)"],
+ on_chunk=lambda chunk: None)
+ self.assertEqual(rc, 5)
+
+ def test_on_chunk_cancel_kills_the_process_and_returns_130(self):
+ cancel = threading.Event()
+ cancel.set()
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c", "import time; time.sleep(60)"],
+ on_chunk=lambda chunk: None, cancel=cancel)
+ self.assertEqual(rc, 130)
+
+ def test_on_chunk_carriage_return_progress_is_forwarded_raw(self):
+ # pip's download bars are \r-only: the hook must see them and the
+ # terminal must get them unsplit.
+ chunks = []
+ captured = io.StringIO()
+ with contextlib.redirect_stdout(captured):
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c",
+ "import sys; sys.stdout.write('dl 1\\rdl 2\\r'); "
+ "sys.stdout.flush()"],
+ on_chunk=chunks.append)
+ self.assertEqual(rc, 0)
+ self.assertEqual(b"".join(chunks), b"dl 1\rdl 2\r")
+ self.assertIn("dl 1\rdl 2\r", captured.getvalue())
+
+
class RunConsoleSubprocessStallTests(unittest.TestCase):
"""The no-output watchdog: a silent child is killed and reported 124."""