summaryrefslogtreecommitdiff
path: root/test/fs.py
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 11:26:42 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit0e6501ce210481c095e6f70a27e7f125f7af3761 (patch)
tree0abf4b55e8eb4f836a3ad10963cbefd94efb8599 /test/fs.py
parent1ac8fbeedaf7cba881a7423b92ead1f739b8ac21 (diff)
downloadpardes-0e6501ce210481c095e6f70a27e7f125f7af3761.tar.gz
pardes-0e6501ce210481c095e6f70a27e7f125f7af3761.zip
A pty/ctl exec that cannot start its shell keeps the one running
Each host closed the running shell before it forked the new one, so an exec whose shell failed left the pane with none and later runs answered error shell gone. A shell not there is now refused up front, and every host starts the new shell first, replacing the old only once the close-on-exec pipe says it ran; a failure there is only said (restartFailed). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/fs.py')
-rw-r--r--test/fs.py40
1 files changed, 28 insertions, 12 deletions
diff --git a/test/fs.py b/test/fs.py
index 977b3e45..6edfeb0f 100644
--- a/test/fs.py
+++ b/test/fs.py
@@ -442,6 +442,27 @@ def run_file(binary):
assert run(client, term, b'true\n') == b'exit 0\n'
assert client.read(f'/pane/{term}/pty/ctl').split()[2] == b'2', client.read(f'/pane/{term}/pty/ctl')
client.write(f'/pane/{term}/pty/ctl', b'winsize 80 24\n')
+ # A shell started again that cannot start (its directory is
+ # there but cannot be entered) fails the write and leaves the
+ # running shell be: runs still work.
+ locked = root / 'locked'
+ locked.mkdir()
+ assert run(client, term, f'cd {locked}\n'.encode()) == b'exit 0\n'
+ deadline = time.monotonic() + 5
+ while str(locked).encode() not in client.read('/index'):
+ assert time.monotonic() < deadline, client.read('/index')
+ time.sleep(.05)
+ locked.chmod(0o600)
+ try:
+ client.write(f'/pane/{term}/pty/ctl', b'exec\n')
+ raise AssertionError('pty/ctl exec of a shell that cannot start was taken')
+ except OSError as refused:
+ assert 'shell' in str(refused), refused
+ finally:
+ locked.chmod(0o755)
+ kept = run(client, term, b'true\n')
+ assert kept == b'exit 0\n', (kept, client.read('/log')[-600:])
+ assert run(client, term, f'cd {root}\n'.encode()) == b'exit 0\n'
with Client(address) as other:
slow = []
waiter = threading.Thread(target=lambda: slow.append(run(other, term, b'sleep 1\n')), daemon=True)
@@ -522,20 +543,15 @@ def new_terminals_named_once(binary):
bad.write_bytes(b'#!/nonexistent/interp\n')
bad.chmod(0o755)
panes = client.read('/index')
- try:
- client.write('/pane/1/ctl', f'Tty {bad}\n'.encode())
- raise AssertionError('Tty of a shell that cannot start was taken')
- except OSError as refused:
- assert 'shell' in str(refused), refused
+ for where, line in (('/pane/1/ctl', f'Tty {bad}\n'), ('/ctl', f'Shell {bad}\n')):
+ try:
+ client.write(where, line.encode())
+ raise AssertionError(f'{line} of a shell that cannot start was taken')
+ except OSError as refused:
+ assert 'interpreter /nonexistent/interp not found' in str(refused), refused
time.sleep(.3)
assert client.read('/index').count(b'\n') == panes.count(b'\n'), client.read('/index')
- client.write('/ctl', f'Shell {bad}\n'.encode())
- try:
- client.write(f'/pane/{made[0]}/pty/ctl', b'exec\n')
- raise AssertionError('pty/ctl exec of a shell that cannot start was taken')
- except OSError as refused:
- assert 'shell' in str(refused), refused
- client.write('/ctl', b'Shell\n')
+ assert b'shell: shell not found' not in client.read('/log'), client.read('/log')
assert str(made[0]).encode() in b' '.join(r.split()[0] for r in client.read('/index').splitlines())