Skip to content

Commit 0267db7

Browse files
committed
Remove the terminal-driving helper for generated tests
The helper let a generated conformance or acceptance test drive its target through the controlling terminal. Attaching it to an execution suppressed the end-of-file the terminal is otherwise given at spawn, on the basis that something would answer the target's reads instead. That trade was applied to every conformance and acceptance execution, while only a test written against the helper ever made it good. Tests that never used it -- nearly all of them -- ran against a terminal whose input simply never ended, so any target reading standard input blocked until the execution timeout. The fix loop then read that timeout as a defect in the generated code and patched against it until the render was abandoned. An interactive command-line application is the worst case: its first prompt is unanswerable, so no functionality after it can pass. Weighed against that, the capability was used once in roughly thirty renders. Removing it deletes the broker, its wire protocol, the helper executable, the capability descriptor, and the portability audit that existed only to keep the helper out of delivered code -- along with the outstanding Windows transport work none of it can ship without. The pseudoterminal backend stays. Giving the target a real terminal is what makes isatty() true and what interactive programs need to start at all; that is independent of anything driving the terminal from outside. The spawn-time end-of-file becomes unconditional, matching the behaviour the pipe backend has always had, and quiet-target re-delivery now applies uniformly rather than only where no driver was attached. Tests that need to drive an interactive program can do so with an established pseudoterminal library, which also leaves the generated suite runnable outside this renderer. Claude-Session: https://claude.ai/code/session_01RwffYaMySLGNKhGyXzDLGG
1 parent ecaa0a8 commit 0267db7

25 files changed

Lines changed: 60 additions & 1913 deletions

‎codeplain_REST_api.py‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ def render_conformance_tests(
322322
conformance_tests_json,
323323
all_acceptance_tests,
324324
run_state: RunState,
325-
platform_test_runtime: Optional[dict] = None,
326325
):
327326
endpoint_url = f"{self.api_url}/render_conformance_tests"
328327
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
@@ -341,9 +340,6 @@ def render_conformance_tests(
341340
"all_acceptance_tests": all_acceptance_tests,
342341
}
343342

344-
if platform_test_runtime is not None:
345-
payload["platform_test_runtime"] = platform_test_runtime
346-
347343
response = self.post_request(endpoint_url, headers, payload, run_state)
348344
return response["patched_response_files"], response["conformance_tests_plan_summary_string"]
349345

@@ -387,7 +383,6 @@ def fix_conformance_tests_issue(
387383
current_testing_frid_high_level_implementation_plan: Optional[str],
388384
conflicting_requirements_count: int,
389385
run_state: RunState,
390-
platform_test_runtime: Optional[dict] = None,
391386
stalled_reason: Optional[str] = None,
392387
):
393388
endpoint_url = f"{self.api_url}/fix_conformance_tests_issue"
@@ -415,9 +410,6 @@ def fix_conformance_tests_issue(
415410
if acceptance_tests is not None:
416411
payload["acceptance_tests"] = acceptance_tests
417412

418-
if platform_test_runtime is not None:
419-
payload["platform_test_runtime"] = platform_test_runtime
420-
421413
# Sent only once the loop has stopped moving. Omitted otherwise, so an
422414
# ordinary fix request is byte-identical to what it was.
423415
if stalled_reason is not None:
@@ -437,7 +429,6 @@ def render_acceptance_tests(
437429
required_modules,
438430
acceptance_test,
439431
run_state: RunState,
440-
platform_test_runtime: Optional[dict] = None,
441432
):
442433
"""
443434
Renders acceptance tests based on the provided parameters.
@@ -477,9 +468,6 @@ def render_acceptance_tests(
477468
"acceptance_test": acceptance_test,
478469
}
479470

480-
if platform_test_runtime is not None:
481-
payload["platform_test_runtime"] = platform_test_runtime
482-
483471
return self.post_request(endpoint_url, headers, payload, run_state)
484472

485473
def analyze_rendering(

‎plain2code_tty.py‎

Lines changed: 0 additions & 137 deletions
This file was deleted.

‎pyproject.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ dev = [
4141

4242
[project.scripts]
4343
codeplain = "plain2code:main"
44-
codeplain-tty = "plain2code_tty:main"
4544

4645
# Derive the version from the git tag (e.g. v0.3.8 -> 0.3.8). The version is
4746
# baked into the package metadata at build time; system_config.py reads it back

‎render_machine/_conpty.py‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* The job is a stronger containment than a POSIX process group. It survives `setpgid`-style
2222
escapes and the kernel enforces it, whereas PTY hangup delivers a signal a target may
2323
ignore.
24-
* There is no synthetic end-of-file. POSIX injects `VEOF` when no input driver is attached;
24+
* There is no synthetic end-of-file. POSIX injects `VEOF` at spawn;
2525
ConPTY has no parent-side equivalent that keeps the input channel open, and the channel
2626
has to stay open for the graceful control byte and for terminal-query replies. A script
2727
that reads input therefore blocks until the execution timeout rather than seeing EOF.
@@ -66,7 +66,6 @@
6666
TERMINAL_ROWS,
6767
InputWriteResult,
6868
TerminalEnvironmentError,
69-
TerminalInputDriver,
7069
TerminalProcess,
7170
TerminalProcessError,
7271
terminal_child_environment,
@@ -165,8 +164,8 @@
165164
# unlike the other backends it cannot hand the target end-of-file, so a script that reads
166165
# terminal input really does block until the execution timeout.
167166
NO_INPUT_NOTE = (
168-
" No input driver was attached to the script's terminal, and on Windows the terminal carries "
169-
"no synthetic end-of-file, so a script that waits for terminal input blocks until the timeout."
167+
" On Windows the terminal carries no synthetic end-of-file, so a script that waits for "
168+
"terminal input blocks until the timeout."
170169
)
171170

172171

@@ -1070,7 +1069,6 @@ def spawn(
10701069
env: Optional[dict] = None,
10711070
terminal_size: Tuple[int, int] = (TERMINAL_COLUMNS, TERMINAL_ROWS),
10721071
stop_event: Optional[threading.Event] = None,
1073-
input_driver: Optional[TerminalInputDriver] = None,
10741072
spawn_timeout: float = HANDSHAKE_TIMEOUT_SECONDS,
10751073
) -> None:
10761074
if self._spawned:

‎render_machine/_legacy_pipe.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
TERMINAL_ROWS,
4545
InputDisposition,
4646
InputWriteResult,
47-
TerminalInputDriver,
4847
TerminalLaunchError,
4948
TerminalProcess,
5049
child_environment,
@@ -111,7 +110,6 @@ def spawn(
111110
env: Optional[dict] = None,
112111
terminal_size: Tuple[int, int] = (TERMINAL_COLUMNS, TERMINAL_ROWS),
113112
stop_event: Optional[threading.Event] = None,
114-
input_driver: Optional[TerminalInputDriver] = None,
115113
) -> None:
116114
if self._spawned:
117115
raise RuntimeError("LegacyPipeProcess instances are single-use")

‎render_machine/_posix_pty.py‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
InputDisposition,
5353
InputWriteResult,
5454
TerminalEnvironmentError,
55-
TerminalInputDriver,
5655
TerminalLaunchError,
5756
TerminalProcess,
5857
TerminalProcessError,
@@ -477,7 +476,6 @@ def __init__(self) -> None:
477476
self._spawned = False
478477
self._closed = False
479478
self._acked = False
480-
self._input_driver: Optional[TerminalInputDriver] = None
481479

482480
self._bundle: Optional[_ReaderBundle] = None
483481
self._reader: Optional[threading.Thread] = None
@@ -513,15 +511,13 @@ def spawn(
513511
env: Optional[dict] = None,
514512
terminal_size: Tuple[int, int] = (TERMINAL_COLUMNS, TERMINAL_ROWS),
515513
stop_event: Optional[threading.Event] = None,
516-
input_driver: Optional[TerminalInputDriver] = None,
517514
handshake_timeout: float = HANDSHAKE_TIMEOUT_SECONDS,
518515
) -> None:
519516
"""Allocates the terminal, launches the target, and returns once it is running."""
520517
if self._spawned:
521518
raise RuntimeError("PosixPtyProcess instances are single-use")
522519
self._spawned = True
523520
self._stop_event = stop_event if stop_event is not None else threading.Event()
524-
self._input_driver = input_driver
525521
deadline = time.monotonic() + handshake_timeout
526522
try:
527523
self._check_cancelled()
@@ -775,11 +771,10 @@ def _advance_handshake(self, parser: _HandshakeParser, status_r: int, deadline:
775771
return False
776772

777773
def _acknowledge(self, deadline: float) -> None:
778-
"""Records the group, delivers the no-driver VEOF, and only then releases the target."""
774+
"""Records the group, delivers the VEOF, and only then releases the target."""
779775
assert self._proc is not None
780776
self._pgid = self._proc.pid # recorded BEFORE the target can run
781-
if self._input_driver is None:
782-
self._inject_veof(deadline)
777+
self._inject_veof(deadline)
783778
self._pre_ack_hook()
784779
self._acked = True
785780
ack_w = self._ack_w

‎render_machine/actions/create_dist.py‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
import file_utils
44
from plain2code_console import SUCCESS_COLOR, console
55
from render_machine.actions.base_action import BaseAction
6-
from render_machine.platform_test_audit import audit_build_folder
76
from render_machine.render_context import RenderContext
87

98

109
class CreateDist(BaseAction):
1110
SUCCESSFUL_OUTCOME = "dist_created"
1211

1312
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
14-
# The final portability audit: a build that references Codeplain's private test
15-
# runtime is never published or copied.
16-
audit_build_folder(render_context.build_folder)
1713
# Copy build and conformance tests folders to output folders if specified
1814
if render_context.copy_build:
1915
file_utils.copy_folder_to_output(

‎render_machine/actions/fix_conformance_test.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from render_machine.actions.base_action import BaseAction
1010
from render_machine.fix_loop_metrics import CONFORMANCE_LOOP, STRATEGY_SWITCH_PREFIX, stalled_reason
1111
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
12-
from render_machine.platform_test_runtime import advertised_platform_test_runtime
1312
from render_machine.render_context import RenderContext
1413
from render_machine.render_types import RenderError, TestExecutionPhase
1514

@@ -217,7 +216,6 @@ def execute(self, render_context: RenderContext, previous_action_payload: Any |
217216
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan,
218217
render_context.conformance_tests_running_context.conflicting_requirement_count,
219218
run_state=render_context.run_state,
220-
platform_test_runtime=advertised_platform_test_runtime(),
221219
stalled_reason=stall_context,
222220
)
223221
code_diff_files_content = {}

‎render_machine/actions/render_conformance_tests.py‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from plain2code_console import console
88
from render_machine.actions.base_action import BaseAction
99
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
10-
from render_machine.platform_test_runtime import advertised_platform_test_runtime
1110
from render_machine.render_context import RenderContext
1211
from render_machine.render_types import AcceptanceTestPhase, TestExecutionPhase
1312

@@ -127,7 +126,6 @@ def _render_conformance_tests(self, render_context: RenderContext):
127126
),
128127
all_acceptance_tests,
129128
run_state=render_context.run_state,
130-
platform_test_runtime=advertised_platform_test_runtime(),
131129
)
132130

133131
render_context.conformance_tests_running_context.current_testing_frid_high_level_implementation_plan = (
@@ -180,7 +178,6 @@ def _render_acceptance_test(self, render_context: RenderContext):
180178
render_context.get_required_modules_functionalities(),
181179
acceptance_test,
182180
run_state=render_context.run_state,
183-
platform_test_runtime=advertised_platform_test_runtime(),
184181
)
185182
conformance_tests_folder_name = (
186183
render_context.conformance_tests_running_context.get_current_conformance_test_folder_name()

‎render_machine/actions/run_conformance_tests.py‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from plain2code_console import console
66
from render_machine.actions.base_action import BaseAction
77
from render_machine.fix_loop_metrics import CONFORMANCE_LOOP, report_fix_loop_attempt
8-
from render_machine.platform_test_runtime import platform_test_runtime_available
98
from render_machine.render_context import RenderContext
109
from render_machine.render_types import RenderError
1110

@@ -50,10 +49,6 @@ def execute(self, render_context: RenderContext, _previous_action_payload: Any |
5049
module=render_context.conformance_tests_running_context.current_testing_module_name,
5150
timeout=render_context.test_script_timeout,
5251
stop_event=render_context.stop_event,
53-
# Conformance (and the acceptance tests that extend the same suite) may drive
54-
# the target's terminal through codeplain-tty; unit tests and environment
55-
# preparation never get the runtime.
56-
platform_test_runtime=platform_test_runtime_available(),
5752
)
5853
render_context.script_execution_history.latest_conformance_test_output_path = (
5954
conformance_tests_temp_log_file_path

0 commit comments

Comments
 (0)